@@ -404,7 +404,7 @@ whereas ``freeze(o, o.__class__)`` freezes both ``o`` and its class
404404explicitly, and at the same time).
405405
406406.. code-block :: python
407- :caption: ** Listing 2. a:** By default, types must be frozen explicitly.
407+ :caption: ** Listing 2. a:** By default, types must be frozen explicitly or freezing fails .
408408
409409 class Foo :
410410 pass
@@ -434,7 +434,7 @@ a module called ``immutable``. The listing below revisits the listing
434434above and uses the ``@frozen `` decorator on ``Foo ``.
435435
436436.. code-block :: python
437- :caption: ** Listing 2. b:** By default, types must be frozen explicitly.
437+ :caption: ** Listing 2. b:** By default, types must be frozen explicitly or else fail .
438438
439439 from immutable import freeze, is_frozen, frozen
440440
@@ -475,7 +475,9 @@ An attempt at mutating ``C`` through ``y`` will result in
475475Freeze propagation is similar to how static annotations such
476476as ``const `` from C or C++ propagate through a code base, except
477477at run-time instead of compile-time. This PEP limits or manages freeze
478- propagation by making user-defined types explicitly freezable,
478+ propagation by only permitting user-defined types to be frozen if they
479+ are frozen *explicitly * (meaning the user passes a direct reference
480+ to the type as an argument to ``freeze() `` or uses a decorator on it)
479481providing a way to hook into the freeze mechanism, and by
480482allowing opting out of freezing altogether or for some limited
481483duration.
@@ -661,7 +663,7 @@ supported since the value is immutable.
661663
662664 # freeze(d) -- will fail unless Die is @frozen or @freezable
663665
664- freeze(Die)
666+ freeze(Die) # After this d can be frozen
665667 is_frozen(Die) # True
666668 is_frozen(Die.roll) # True
667669
@@ -707,16 +709,16 @@ Note that freezing is *in-place*; ``freeze(obj)`` freezes ``obj``, not a copy.
707709
708710.. _freezable :
709711
710- Freezability - Unfreezable and explicitly freezable objects
711- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
712+ Freezability - Unfreezable objects and objects which must be explicitly frozen
713+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
712714
713715The immutable module provides the function ``set_freezable(obj, status=Yes) ``
714716which controls if and how an object is freezable. Most
715717objects are freezable by default, meaning that freezing can propagate
716- to them. However, functions and types are explicitly freezable by
717- default (`` set_freezable(obj, Explicit) ``) meaning that freezing
718- will never propagate to them and they can only be frozen when they
719- are explicitly passed in to `` freeze() ``. Objects can also be marked as
718+ to them. However, types cannot be frozen through propagation by
719+ default -- they can only be frozen when they
720+ are explicitly passed in to `` freeze() `` (`` set_freezable(obj, Explicit) ``).
721+ Objects can also be marked as
720722unfreezable (``set_freezable(obj, No) ``) which will result in an error
721723when someone attempts to freeze the object. The values for ``Yes ``,
722724``No `` and ``Explicit `` are defined in the immutable module.
@@ -899,6 +901,34 @@ itself during initialisation.
899901 current_module = sys.modules[__name__ ]
900902 set_freezable(current_module, immutable.Proxy)
901903
904+
905+ Accessing subclass information and subclassing immutable classes
906+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
907+
908+ When a class object becomes immutable, its base classes
909+ replace their interpreter-local registry of mutable
910+ subclasses with an internal, shared list of weak references
911+ to immutable subclasses. All mutable subclasses remain
912+ recorded in interpreter-local registries (also using
913+ weak references). Any subsequent subclassing of the base
914+ in a given interpreter adds the new subclass to that
915+ interpreter's local registry.
916+
917+ Let ``A `` be an immutable class and ``B `` an immutable subclass of
918+ ``A ``. When ``B `` is made immutable, its weak reference is moved
919+ from the interpreter-local registry into ``A ``'s shared list of
920+ immutable subclasses.
921+
922+ Calls to ``type.__subclasses__() `` in any interpreter return
923+ a fresh list containing all live immutable subclasses plus
924+ the interpreter's own mutable subclasses. Publication of
925+ immutable subclasses across interpreters is eventually
926+ consistent.
927+
928+ Note that once a class is immutable, reassignment of
929+ ``__bases__ `` is prohibited.
930+
931+
902932.. _summary-2 :
903933
904934Summary
@@ -1164,14 +1194,15 @@ wants to limit immutability to something that happens only
11641194at creation. This is not compatible with Python patterns like
11651195monkey patching and cyclic structures. (Or how types are defined.)
11661196
1167- By making classes * explicitly freezable * we avoid freezing one
1197+ By making classes require an explicit call to freeze we avoid freezing one
11681198object propagating to all objects of the same type at the same
11691199time as we stop careless freezing of objects. To make a class
1170- freezable, code must explicitly make it so, through an
1171- ``@frozen `` (at definition-time), ``@freezable `` opting in to
1172- being frozen as a side-effect of freezing an instance, or through
1173- an explicit call to ``freeze() `` on the type object itself. This
1174- serves as documentation similar to the ``const `` propagation
1200+ immutable, code must explicitly make it so, through a ``@frozen ``
1201+ decorator at definition-time, or through an explicit call to ``freeze() ``
1202+ on the type object itself. By using ``@freezable `` a declaration opts
1203+ in to being frozen as a side-effect of freezing an instance.
1204+ (A call to ``set_freezable(cls, Yes) `` has the same effect).
1205+ This serves as documentation similar to the ``const `` propagation
11751206above, even though -- as Python is a dynamically checked language --
11761207this ``const ``-like propagation will be driven by run-time errors
11771208rather than compile-time.
@@ -1242,8 +1273,8 @@ and a proxy mode for modules.
12421273
12431274**Freezing rules: **
12441275
1245- - Objects which are explicitly freezable (this includes all type
1246- objects) must be frozen explicitly -- not indirectly
1276+ - Objects which are explicit-only freezable (this includes all type
1277+ objects) must be frozen by an explicit call to `` freeze `` -- not indirectly
12471278 via freeze propagation. (Other attempts fail.)
12481279- Freezing an object graph fails if it contains objects that cannot be frozen.
12491280- An individual object can be made impossible to freeze by setting
@@ -1397,7 +1428,7 @@ freeze.
13971428 Dealing with cyclic dependencies
13981429~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
13991430
1400- Objects that are explicitly freezable can be in a cyclic
1431+ Objects that require explicit freezing can be in a cyclic
14011432dependency.
14021433
14031434.. code-block :: python
@@ -1412,10 +1443,10 @@ dependency.
14121443 self .value = A()
14131444
14141445 Notably, freezing ``A `` freezes ``A.foo `` which captures ``B ``.
1415- However, since ``B `` is explicitly freezable , freezing ``A.foo ``
1446+ However, since ``B `` requires explicit freezing , freezing ``A.foo ``
14161447will fail. Trying to first freeze ``B `` does not solve the
14171448problem, as ``B.bar `` fails to freeze ``A `` which is also
1418- explicitly freezable . The solution to this problem is to let
1449+ requires explicit freezing . The solution to this problem is to let
14191450``freeze `` take multiple arguments which can be used to resolve
14201451these kinds of situations: ``freeze(A, B) `` will permit ``A.foo ``
14211452to capture ``B `` because it sees that ``B `` is in the list of
0 commit comments