@@ -36,7 +36,8 @@ specification:
3636* The ``SOURCE `` format is renamed to ``STRING `` to improve clarity and reduce the risk of
3737 user confusion.
3838* Conditionally defined class and module annotations are handled correctly.
39- * Accessing annotations on a partially executed module will raise :py:exc: `RuntimeError `.
39+ * If annotations are accessed a partially executed module, the annotations executed so far
40+ are returned, but not cached.
4041
4142Motivation
4243==========
@@ -793,8 +794,8 @@ circumstances:
793794* Module and class bodies are only executed once.
794795* The annotations of a class are not externally visible until execution of the
795796 class body is complete. For modules, this is not quite true, because a partially
796- executed module can be visible to other imported modules, but this is an
797- unusual case that is problematic for other reasons (see the next section).
797+ executed module can be visible to other imported modules, but this case is
798+ problematic for other reasons (see the next section).
798799
799800This allows the following implementation strategy:
800801
@@ -842,7 +843,7 @@ Consider this example:
842843 from . import a
843844 print (" in b:" , a.__annotations__ )
844845
845- Note that while ``.py `` executes, the ``recmod.a `` module is defined,
846+ Note that while ``recmod/b .py `` executes, the ``recmod.a `` module is defined,
846847but has not yet finished execution.
847848
848849On 3.13, this produces:
@@ -866,14 +867,12 @@ Specification
866867-------------
867868
868869Accessing ``__annotations__ `` on a partially executed module will
869- raise :py:exc: `RuntimeError `. After module execution is complete,
870- accessing ``__annotations__ `` will execute and cache the annotations as
871- normal.
872-
873- This is technically a compatibility break for code that introspects
874- annotations on partially executed modules, but that should be a rare
875- case. It is better to couple this compatibility break with the other
876- changes in annotations behavior introduced by this PEP and :pep: `649 `.
870+ continue to return the annotations that have been executed so far,
871+ similar to the behavior in earlier versions in Python. However, in this
872+ case the ``__annotations__ `` dictionary will not be cached, so later
873+ accesses to the ``__annotations__ `` attribute will return a fresh dictionary.
874+ This is necessary because ``__annotate__ `` must be called again in order to
875+ incorporate additional annotations.
877876
878877
879878Miscellaneous implementation details
@@ -964,16 +963,28 @@ to be supported by third-party libraries. Nevertheless, it is a serious issue fo
964963that perform introspection, and it is important that we make it as easy as possible for
965964libraries to support the new semantics in a straightforward, user-friendly way.
966965
967- We will update those parts of the standard library that are affected by this problem,
968- and we propose to add commonly useful functionality to the new ``annotationlib `` module,
969- so third-party tools can use the same set of tools.
966+ Several pieces of functionality in the standard library are affected by this issue,
967+ including :mod: `dataclasses `, :class: `typing.TypedDict ` and :class: `typing.NamedTuple `.
968+ These have been updated to support this pattern using the functionality in the new
969+ ``annotationlib `` module.
970970
971971
972972Security Implications
973973=====================
974974
975- None.
976-
975+ One consequence of :pep: `649 ` is that accessing annotations on an object, even if
976+ the object is a function or a module, may now execute arbitrary code. This is true
977+ even if the STRING format is used, because the stringifier mechanism only overrides
978+ the global namespace, and that is not enough to sandbox Python code completely.
979+
980+ In previous Python versions, accessing the annotations of functions or modules
981+ could not execute arbitrary code, but classes and other objects could already
982+ execute arbitrary code on access of the ``__annotations__ `` attribute.
983+ Similarly, almost any further introspection on the annotations (e.g.,
984+ using ``isinstance() ``, calling functions like ``typing.get_origin ``, or even
985+ displaying the annotations with ``repr() ``) could already execute arbitrary code.
986+ And of course, accessing annotations from untrusted code implies that the untrusted
987+ code has already been imported.
977988
978989How to Teach This
979990=================
0 commit comments