Sets can only contain immutable elements. For convenience, mutableSet objects are automatically copied to anImmutableSetbefore being added as a set element.
The mechanism is to always add a hashable element, or if it is nothashable, the element is checked to see if it has an__as_immutable__() method which returns an immutable equivalent.
SinceSet objects have a__as_immutable__() methodreturning an instance ofImmutableSet, it is possible toconstruct sets of sets.
A similar mechanism is needed by the__contains__() andremove() methods which need to hash an element to checkfor membership in a set. Those methods check an element for hashabilityand, if not, check for a__as_temporarily_immutable__() methodwhich returns the element wrapped by a class that provides temporarymethods for__hash__(),__eq__(), and__ne__().
The alternate mechanism spares the need to build a separate copy ofthe original mutable object.
Set objects implement the__as_temporarily_immutable__()method which returns theSet object wrapped by a new class_TemporarilyImmutableSet.
The two mechanisms for adding hashability are normally invisible to theuser; however, a conflict can arise in a multi-threaded environmentwhere one thread is updating a set while another has temporarily wrapped itin_TemporarilyImmutableSet. In other words, sets of mutable setsare not thread-safe.