Skip to content

Commit a111ec4

Browse files
larryhastingshugovkJelleZijlstraAlexWaygoodhauntsaninja
authored
PEP 649: Improve description of semantics and mark as accepted (#3138)
* Improve PEP 649's description of its semantics. * Stipulate that name resolution for annotations under 649 must be *identical* to stock semantics. * *Don't* specify exactly the mechanism that conformant implementations must use to implement 649. Instead, *do* describe how CPython might do it, but leave the actual details of how to implement 649 up to each language implementation. * Incorporate Jelle's suggestion that the formats for inspect.get_annotations() be in an enum.IntEnum. * Fix lint. * PEP 693: Postpone 3.12.0b1 by two weeks (#3139) * PEP 695: Lazy evaluation, concrete scoping semantics, other changes (#3122) - Lazy evaluation means that referencing a later type variable works at runtime - Disallow walrus in TypeVar bounds, and also disallow yield/yield from/await in the same contexts - Remove rejection of lambda lifting; that is the implementation we are using now - Change the AST - Change of direction on mangling - More precise scoping rules Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com> Co-authored-by: Shantanu <12621235+hauntsaninja@users.noreply.github.com> * Incorporate changes from feedback, mark Accepted. * Fix PEP 12 header *order compliance*. Wow. * Fix Sphinx complaints. * Make enum consistent, flesh out observed semantics. * Add "Resolution" header, as pointed out by Hugo. * Switch to other URL for Resolution header. * Apply ``global_enum`` to ``inspect.AnnotationFormat`` * Final? text / semantics cleanup pass. * "accept" -> "accepts". Bettering my Englishes. * Add new "post history" reflecting the updates. * Update post history with all conversations, courtesy CAM! Co-authored-by: C.A.M. Gerlach <CAM.Gerlach@Gerlach.CAM> * Fix typo. Thanks, Emily! Co-authored-by: Emily Morehouse <emilyemorehouse@gmail.com> * Add "Discussions-To" header. Thanks, CAM! Co-authored-by: C.A.M. Gerlach <CAM.Gerlach@Gerlach.CAM> * Attempt to satisfy "validate-post-history" hook. --------- Co-authored-by: Hugo van Kemenade <hugovk@users.noreply.github.com> Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com> Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com> Co-authored-by: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Co-authored-by: Adam Turner <9087854+aa-turner@users.noreply.github.com> Co-authored-by: C.A.M. Gerlach <CAM.Gerlach@Gerlach.CAM> Co-authored-by: Emily Morehouse <emilyemorehouse@gmail.com>
1 parent 85db95a commit a111ec4

File tree

1 file changed

+80
-66
lines changed

1 file changed

+80
-66
lines changed

pep-0649.rst

Lines changed: 80 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,25 @@
11
PEP: 649
22
Title: Deferred Evaluation Of Annotations Using Descriptors
33
Author: Larry Hastings <larry@hastings.org>
4-
Status: Draft
4+
Discussions-To: https://discuss.python.org/t/pep-649-deferred-evaluation-of-annotations-tentatively-accepted/21331/
5+
Status: Accepted
56
Type: Standards Track
67
Topic: Typing
78
Content-Type: text/x-rst
89
Created: 11-Jan-2021
9-
Post-History: 11-Jan-2021, 11-Apr-2021, 19-Apr-2023
10-
10+
Python-Version: 3.13
11+
Post-History: `11-Jan-2021 <https://mail.python.org/archives/list/python-dev@python.org/thread/5QMMCRF4HTRRNJV56CGHVI5GRHVBDGQO/>`__,
12+
`12-Apr-2021 <https://mail.python.org/archives/list/python-dev@python.org/thread/QSASX6PZ3LIIFIANHQQFS752BJYFUFPY/>`__,
13+
`18-Apr-2021 <https://mail.python.org/archives/list/python-dev@python.org/thread/WUZGTGE43T7XV3EUGT6AN2N52OD3U7AE/>`__,
14+
`09-Aug-2021 <https://mail.python.org/archives/list/python-dev@python.org/thread/2MEOWHCVDLPABOBLYUGRXVOOOBYOLLU6/>`__,
15+
`20-Oct-2021 <https://mail.python.org/archives/list/python-dev@python.org/thread/SZLWVYV2HPLU6AH7DOUD7DWFUGBJGQAY/>`__,
16+
`20-Oct-2021 <https://discuss.python.org/t/type-annotations-pep-649-and-pep-563/11363>`__,
17+
`17-Nov-2021 <https://mail.python.org/archives/list/python-dev@python.org/thread/VIZEBX5EYMSYIJNDBF6DMUMZOCWHARSO/>`__,
18+
`15-Mar-2022 <https://discuss.python.org/t/finding-edge-cases-for-peps-484-563-and-649-type-annotations/14314>`__,
19+
`23-Nov-2022 <https://discuss.python.org/t/pep-649-deferred-evaluation-of-annotations-tentatively-accepted/21331>`__,
20+
`07-Feb-2023 <https://discuss.python.org/t/two-polls-on-how-to-revise-pep-649/23628>`__,
21+
`11-Apr-2023 <https://discuss.python.org/t/a-massive-pep-649-update-with-some-major-course-corrections/25672>`__,
22+
Resolution: https://discuss.python.org/t/pep-649-deferred-evaluation-of-annotations-tentatively-accepted/21331/43
1123

1224
********
1325
Abstract
@@ -75,6 +87,7 @@ in a specific format.
7587
Format identifiers are always predefined integer values.
7688
The formats defined by this PEP are:
7789

90+
7891
* ``inspect.VALUE = 1``
7992

8093
The default value.
@@ -528,6 +541,31 @@ resulting in this PEP.
528541
Implementation
529542
**************
530543

544+
Observed semantics for annotations expressions
545+
==============================================
546+
547+
For any object ``o`` that supports annotations,
548+
provided that all names evaluated in the annotations expressions
549+
are bound before ``o`` is defined and never subsequently rebound,
550+
``o.__annotations__`` will produce an identical annotations dict both
551+
when "stock" semantics are active and when this PEP is active.
552+
In particular, name resolution will be performed identically in
553+
both scenarios.
554+
555+
When this PEP is active, the value of ``o.__annotations__``
556+
won't be calculated until the first time ``o.__annotations__``
557+
itself is evaluated. All evaluation of the annotation expressions
558+
is delayed until this moment, which also means that
559+
560+
* names referenced in the annotations expressions will use their
561+
*current* value at this moment, and
562+
* if evaluating the annotations expressions raises an exception,
563+
that exception will be raised at this moment.
564+
565+
Once ``o.__annotations__`` is successfully calculated for the
566+
first time, this value is cached and will be returned by future
567+
requests for ``o.__annotations__``.
568+
531569
__annotate__ and __annotations__
532570
================================
533571

@@ -556,9 +594,9 @@ code should prefer to interact with it only via the
556594

557595
The callable stored in ``__annotate__`` must accept a
558596
single required positional argument called ``format``,
559-
which will always be an ``int``. It must either return
560-
a dict (or subclass of dict) or raise
561-
``NotImplementedError()``.
597+
which will always be an ``int`` (or a subclass of ``int``).
598+
It must either return a dict (or subclass of dict) or
599+
raise ``NotImplementedError()``.
562600

563601
Here's a formal definition of ``__annotate__``, as it will
564602
appear in the "Magic methods" section of the Python
@@ -573,25 +611,25 @@ Language Reference:
573611
annotations values should be provided. Must be one of the
574612
following:
575613

576-
``1`` (exported as ``inspect.VALUE``)
614+
``inspect.VALUE`` (equivalent to the ``int`` constant ``1``)
577615

578616
Values are the result of evaluating the annotation expressions.
579617

580-
``2`` (exported as ``inspect.SOURCE``)
618+
``inspect.FORWARDREF`` (equivalent to the ``int`` constant ``2``)
619+
620+
Values are real annotation values (as per ``inspect.VALUE`` format)
621+
for defined values, and ``ForwardRef`` proxies for undefined values.
622+
Real objects may be exposed to, or contain references to,
623+
``ForwardRef`` proxy objects.
624+
625+
``inspect.SOURCE`` (equivalent to the ``int`` constant ``3``)
581626

582627
Values are the text string of the annotation as it
583628
appears in the source code. May only be approximate;
584629
whitespace may be normalized, and constant values may
585630
be optimized. It's possible the exact values of these
586631
strings could change in future version of Python.
587632

588-
``3`` (exported as ``inspect.FORWARDREF``)
589-
590-
Values are real annotation values (as per ``inspect.VALUE`` format)
591-
for defined values, and ``ForwardRef`` proxies for undefined values.
592-
Real objects may be exposed to, or contain references to,
593-
``ForwardRef`` proxy objects.
594-
595633
If an ``__annotate__`` function doesn't support the requested
596634
format, it must raise ``NotImplementedError()``.
597635
``__annotate__`` functions must always support ``1`` (``inspect.VALUE``)
@@ -713,25 +751,12 @@ makes some modifications to the annotations before it returns them.
713751
This PEP adds a new keyword-only parameter to these two functions,
714752
``format``. ``format`` specifies what format the values in the
715753
annotations dict should be returned in.
716-
``format`` accepts the following values, defined as attributes on the
717-
``inspect`` module::
718-
719-
VALUE = 1
720-
FORWARDREF = 2
721-
SOURCE = 3
754+
The ``format`` parameter on these two functions accepts the same values
755+
as the ``format`` parameter on the ``__annotate__`` magic method
756+
defined above; however, these ``format`` parameters also have a default
757+
value of ``inspect.VALUE``.
722758

723-
The default value for the ``format`` parameter is ``1``,
724-
which is ``VALUE`` format.
725-
726-
The defined ``format`` values are guaranteed to be contiguous,
727-
and the ``inspect`` module also publishes attributes representing
728-
the minimum and maximum supported ``format`` values::
729-
730-
FORMAT_MIN = VALUE
731-
FORMAT_MAX = SOURCE
732-
733-
734-
Also, when either ``__annotations__`` or ``__annotate__`` is updated on an
759+
When either ``__annotations__`` or ``__annotate__`` is updated on an
735760
object, the other of those two attributes is now out-of-date and should also
736761
either be updated or deleted (set to ``None``, in the case of ``__annotate__``
737762
which cannot be deleted). In general, the semantics established in the previous
@@ -1017,40 +1042,29 @@ the wrapped callable, which for simplicity must be named
10171042
return ann
10181043

10191044

1020-
Other modifications to existing objects
1021-
=======================================
1045+
Other modifications to the Python runtime
1046+
=========================================
10221047

1023-
This PEP adds two more attributes to existing Python objects:
1024-
a ``__locals__`` attribute to function objects, and
1025-
an optional ``__globals__`` attribute to class objects.
1026-
1027-
In Python, the bytecode interpreter can reference both a
1028-
"globals" and a "locals" dictionary. However, the current
1029-
function object can only be bound to a globals dictionary,
1030-
via the ``__globals__`` attribute. Traditionally the
1031-
"locals" dictionary is only set when executing a class.
1032-
This PEP needs to set the "locals" dictionary to the class dict
1033-
when evaluating annotations defined inside a class namespace.
1034-
So this PEP defines a new ``__locals__`` attribute on
1035-
functions. By default it is uninitialized, or rather is set
1036-
to an internal value that indicates it hasn't been explicitly set.
1037-
It can be set to either ``None`` or a dictionary. If it's set to
1038-
a dictionary, the interpreter will use that dictionary as
1039-
the "locals" dictionary when running the function.
1040-
1041-
In Python, function objects contain a reference to their own
1042-
``__globals__``. However, class objects aren't currently
1043-
defined as doing so in Python. The implementation of
1044-
``__annotate__`` in CPython needs a reference to the module
1045-
globals in order to bind the unbound code object. So this PEP
1046-
defines a new ``__globals__`` attribute on class objects,
1047-
which stores a reference to the globals for the module where
1048-
the class was defined. Note that this attribute is optional,
1049-
but was useful for the CPython implementation.
1050-
1051-
(The class ``__globals__`` attribute does create a new reference
1052-
cycle, between a class and its module. However, any class that
1053-
contains a method already participates in at least one such cycle.)
1048+
This PEP does not dictate exactly how it should be
1049+
implemented; that is left up to the language implementation
1050+
maintainers. However, the best implementation of this
1051+
PEP may require adding additional information to existing
1052+
Python objects, which is implicitly condoned by the acceptance
1053+
of this PEP.
1054+
1055+
For example, it may be necessary to add a
1056+
``__globals__`` attribute to class objects, so that the
1057+
``__annotate__`` function for that class can be lazily
1058+
bound, only on demand. Also, ``__annotate__`` functions
1059+
defined on methods defined in a class may need to retain
1060+
a reference to the class's ``__dict__``, in order to
1061+
correctly evaluate names bound in that class. It's expected
1062+
that the CPython implementation of this PEP will include
1063+
both those new attributes.
1064+
1065+
All such new information added to existing Python objects
1066+
should be done with "dunder" attributes, as they will of
1067+
course be implementation details.
10541068

10551069

10561070
Interactive REPL Shell

0 commit comments

Comments
 (0)