@@ -27,7 +27,9 @@ specification:
27
27
* We specify the behavior of wrapper objects that provide annotations, such as :py:func: `classmethod `
28
28
and code that uses :py:func: `functools.wraps `.
29
29
* There will not be a code flag for marking ``__annotate__ `` functions
30
- that can be run in a "fake globals" environment.
30
+ that can be run in a "fake globals" environment. Instead, we add a fourth format,
31
+ ``VALUE_WITH_FAKE_GLOBALS ``, to allow third-party implementors of annotate functions to
32
+ indicate what formats they support.
31
33
* Setting the ``__annotations__ `` attribute directly will not affect the ``__annotate__ `` attribute.
32
34
* We add functionality to allow evaluating type alias values and type parameter bounds and defaults
33
35
(which were added by :pep: `695 ` and :pep: `696 `) using PEP 649-like semantics.
@@ -74,6 +76,11 @@ We suggest the following deprecation plan:
74
76
75
77
- In Python 3.14, ``from __future__ import annotations `` will continue to work as it
76
78
did before, converting annotations into strings.
79
+
80
+ - If the future import is active, the ``__annotate__ `` function of objects with
81
+ annotations will return the annotations as strings when called with the ``VALUE ``
82
+ format, reflecting the behavior of ``__annotations__ ``.
83
+
77
84
- Sometime after the last release that did not support :pep: `649 ` semantics (expected to be 3.13)
78
85
reaches its end-of-life, ``from __future__ import annotations `` is deprecated. Compiling
79
86
any code that uses the future import will emit a :py:exc: `DeprecationWarning `. This will
@@ -194,7 +201,8 @@ The module will contain the following functionality:
194
201
* ``Format ``: an enum that contains the possible formats of annotations. This will
195
202
replace the ``VALUE ``, ``FORWARDREF ``, and ``SOURCE `` formats in :pep: `649 `.
196
203
PEP 649 proposed to make these values global members of the :py:mod: `inspect `
197
- module; we prefer to place them within an enum.
204
+ module; we prefer to place them within an enum. We propose to add a fourth format,
205
+ ``VALUE_WITH_FAKE_GLOBALS `` (see below).
198
206
* ``ForwardRef ``: a class representing a forward reference; it may be returned by
199
207
``get_annotations() `` when the format is ``FORWARDREF ``. The existing class
200
208
:py:class: `typing.ForwardRef ` will become an alias of this class. Its members include:
@@ -251,6 +259,9 @@ What should this module be called? Some ideas:
251
259
and ``from __future__ import annotations `` in the same module. The use of a common word
252
260
as the name will make the module harder to search for. There is a PyPI package :pypi: `annotations `,
253
261
but it had only a single release in 2015 and looks abandoned.
262
+ - ``annotation `` (in the singular): Similar, but does not cause confusion with the future
263
+ import. There is an abandoned PyPI package :pypi: `annotation `, but it apparently never
264
+ released any artifacts.
254
265
- ``annotools ``: Analogous to :py:mod: `itertools ` and :py:mod: `functools `, but "anno" is a less
255
266
obvious abbreviation than "iter" or "func". As of this writing, there
256
267
is no PyPI package with this name.
@@ -561,8 +572,8 @@ This approach would also mean that accessing ``.__annotations__`` on an instance
561
572
of an annotated class no longer works. While this behavior is not documented,
562
573
it is a long-standing feature of Python and is relied upon by some users.
563
574
564
- Remove code flag for marking `` __annotate__ `` functions
565
- =======================================================
575
+ Adding the `` VALUE_WITH_FAKE_GLOBALS `` format
576
+ =============================================
566
577
567
578
:pep: `649 ` specifies:
568
579
@@ -577,33 +588,46 @@ Remove code flag for marking ``__annotate__`` functions
577
588
it's expected that only ``__annotate__ `` methods generated
578
589
by the Python compiler will set it.
579
590
580
- We have not found a need for this mechanism during our work to
581
- add :pep: `649 ` support to the standard library. While it is true
582
- that custom ``__annotate__ `` functions may not work well with the
583
- "fake globals" environment, this technique is used only when the
584
- ``__annotate__ `` function raises :py:exc: `NotImplementedError ` to
585
- signal that it does not support the requested format. However,
586
- manually implemented ``__annotate__ `` functions are likely to support
587
- all three annotation formats; often, they will consist of a call to
588
- ``annotationlib.call_annotate_function `` plus some transformation of the
589
- result.
590
-
591
- In addition, the proposed mechanism couples the implementation with
591
+ However, this mechanism couples the implementation with
592
592
low-level details of the code object. The code object flags are
593
593
CPython-specific and the documentation :py:ref: `explicitly warns <inspect-module-co-flags >`
594
594
against relying on the values.
595
595
596
+ Larry Hastings suggested an alternative approach that does not
597
+ rely on code flags: a fourth format, ``VALUE_WITH_FAKE_GLOBALS ``.
598
+ Compiler-generated annotate functions would support only the
599
+ ``VALUE `` and ``VALUE_WITH_FAKE_GLOBALS `` formats, both of which are
600
+ implemented identically. The standard library would use the
601
+ ``VALUE_WITH_FAKE_GLOBALS `` format when invoking an annotate function
602
+ in one of the special "fake globals" environments.
603
+
604
+ This approach is useful as a forward-compatible mechanism for
605
+ adding new annotation formats in the future. Users who manually
606
+ write annotate functions should raise ``NotImplementedError `` if
607
+ the ``VALUE_WITH_FAKE_GLOBALS `` format is requested, so the standard
608
+ library will not call the manually written annotate function with
609
+ "fake globals", which could have unpredictable results.
610
+
596
611
Specification
597
612
-------------
598
613
599
- The standard library will use the "fake globals" technique on any
600
- ``__annotate__ `` function that raises :py:exc: `NotImplementedError `
601
- when the requested format is not supported.
614
+ An additional format, ``FAKE_GLOBALS_VALUE ``, is added to the ``Format `` enum in the
615
+ ``annotationlib `` module, with value equal to 2. (As a result, the values of the
616
+ other formats will shift relative to PEP 649: ``FORWARDREF `` will be 3 and ``SOURCE ``
617
+ will be 4.)
618
+
619
+ Compiler-generated
620
+ annotate functions will support this format and return the same value as
621
+ they would return for the ``VALUE `` format. The standard library will pass
622
+ this format to the ``__annotate__ `` function when it is called in a "fake globals"
623
+ environment, as used to implement the ``FORWARDREF `` and ``SOURCE `` formats.
624
+ All public functions in the ``annotationlib `` module that accept a format
625
+ argument will raise :py:exc: `NotImplementedError ` if the format is ``FAKE_GLOBALS_VALUE ``.
602
626
603
- Third-party code that implements ``__annotate__ `` functions should either
604
- support all three annotation formats, or be prepared to handle the
605
- "fake globals" environment. This should be mentioned in the data model
606
- documentation for ``__annotate__ ``.
627
+ Third-party code that implements ``__annotate__ `` functions should raise
628
+ :py:exc: ` NotImplementedError ` if the `` FAKE_GLOBALS_VALUE `` format is passed
629
+ and the function is not prepared to be run in a "fake globals" environment.
630
+ This should be mentioned in the data model documentation for ``__annotate__ ``.
607
631
608
632
Effect of setting ``__annotations__ ``
609
633
=====================================
@@ -754,7 +778,7 @@ Signature of ``__annotate__`` functions
754
778
``__annotate__(format: int) -> dict ``
755
779
756
780
However, using ``format `` as a parameter name could lead to collisions
757
- if an annotation uses a class named ``format ``. The parameter should be
781
+ if an annotation uses a symbol named ``format ``. The parameter should be
758
782
positional-only and have a name that cannot be a legal identifier in order
759
783
to avoid this problem.
760
784
@@ -846,7 +870,8 @@ initial decisions, but the overall design is still his.
846
870
847
871
I thank Carl Meyer and Alex Waygood for feedback on early drafts of this PEP. Alex Waygood,
848
872
Alyssa Coghlan, and David Ellis provided insightful feedback and suggestions on the
849
- interaction between metaclasses and ``__annotations__ ``.
873
+ interaction between metaclasses and ``__annotations__ ``. Larry Hastings also provided useful
874
+ feedback on this PEP.
850
875
851
876
Appendix
852
877
========
0 commit comments