Skip to content
Merged
Changes from 1 commit
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
d9a17ff
Improve PEP 649's description of its semantics.
larryhastings May 5, 2023
23148f6
Fix lint.
larryhastings May 5, 2023
9ace095
PEP 693: Postpone 3.12.0b1 by two weeks (#3139)
hugovk May 8, 2023
108f275
PEP 695: Lazy evaluation, concrete scoping semantics, other changes (…
JelleZijlstra May 8, 2023
8989c52
Incorporate changes from feedback, mark Accepted.
larryhastings May 8, 2023
af3aa36
Fix PEP 12 header *order compliance*. Wow.
larryhastings May 8, 2023
7af54df
Fix Sphinx complaints.
larryhastings May 8, 2023
0034059
Merge branch 'main' into nail_down_annotation_expression_semantics
JelleZijlstra May 8, 2023
3d34d84
Make enum consistent, flesh out observed semantics.
larryhastings May 9, 2023
06d53a4
Add "Resolution" header, as pointed out by Hugo.
larryhastings May 9, 2023
1a316cc
Switch to other URL for Resolution header.
larryhastings May 9, 2023
08485e9
Apply ``global_enum`` to ``inspect.AnnotationFormat``
AA-Turner May 9, 2023
72b8183
Final? text / semantics cleanup pass.
larryhastings May 10, 2023
ade4a90
"accept" -> "accepts". Bettering my Englishes.
larryhastings May 10, 2023
0503ca1
Add new "post history" reflecting the updates.
larryhastings May 10, 2023
7da747a
Update post history with all conversations, courtesy CAM!
larryhastings May 15, 2023
c9b0773
Fix typo. Thanks, Emily!
larryhastings May 15, 2023
c36b491
Add "Discussions-To" header. Thanks, CAM!
larryhastings May 15, 2023
7896e98
Attempt to satisfy "validate-post-history" hook.
larryhastings May 16, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 51 additions & 44 deletions pep-0649.rst
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,20 @@ resulting in this PEP.
Implementation
**************

Observed semantics for annotations expressions
==============================================

For any object ``o`` that supports annotations,
``o.__annotations__`` will produce an identical
annotations dict under this PEP as it would
under "stock" semantics, provided that none of
the names referenced in the annotations expressions
are subsequently rebound.

In particular, when this PEP is active, name
resolution in annotations must be *identical*
to stock semantics.

__annotate__ and __annotations__
================================

Expand Down Expand Up @@ -556,8 +570,9 @@ code should prefer to interact with it only via the

The callable stored in ``__annotate__`` must accept a
single required positional argument called ``format``,
which will always be an ``int``. It must either return
a dict (or subclass of dict) or raise
which will always be an ``int`` or an object interchangable
with an ``int`` (e.g. ``enum.IntEnum``). It must either
return a dict (or subclass of dict) or raise
``NotImplementedError()``.

Here's a formal definition of ``__annotate__``, as it will
Expand All @@ -573,19 +588,19 @@ Language Reference:
annotations values should be provided. Must be one of the
following:

``1`` (exported as ``inspect.VALUE``)
``inspect.VALUE`` (equivalent to the ``int`` constant ``1``)

Values are the result of evaluating the annotation expressions.

``2`` (exported as ``inspect.SOURCE``)
``inspect.SOURCE`` (equivalent to the ``int`` constant``2``)

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

``3`` (exported as ``inspect.FORWARDREF``)
``inspect.FORWARDREF`` (equivalent to the ``int`` constant ``3``)

Values are real annotation values (as per ``inspect.VALUE`` format)
for defined values, and ``ForwardRef`` proxies for undefined values.
Expand Down Expand Up @@ -713,15 +728,18 @@ makes some modifications to the annotations before it returns them.
This PEP adds a new keyword-only parameter to these two functions,
``format``. ``format`` specifies what format the values in the
annotations dict should be returned in.
``format`` accepts the following values, defined as attributes on the
``format`` accepts the following values, as defined the
``inspect`` module::

VALUE = 1
FORWARDREF = 2
SOURCE = 3
class AnnotationFormat(enum.IntEnum):
VALUE = 1
FORWARDREF = 2
SOURCE = 3
VALUE = AnnotationFormat.VALUE
FORWARDREF = AnnotationFormat.FORWARDREF
SOURCE = AnnotationFormat.SOURCE

The default value for the ``format`` parameter is ``1``,
which is ``VALUE`` format.
The default value for the ``format`` parameter is ``inspect.VALUE``.

The defined ``format`` values are guaranteed to be contiguous,
and the ``inspect`` module also publishes attributes representing
Expand Down Expand Up @@ -1017,40 +1035,29 @@ the wrapped callable, which for simplicity must be named
return ann


Other modifications to existing objects
=======================================
Other modifications to the Python runtime
=========================================

This PEP adds two more attributes to existing Python objects:
a ``__locals__`` attribute to function objects, and
an optional ``__globals__`` attribute to class objects.

In Python, the bytecode interpreter can reference both a
"globals" and a "locals" dictionary. However, the current
function object can only be bound to a globals dictionary,
via the ``__globals__`` attribute. Traditionally the
"locals" dictionary is only set when executing a class.
This PEP needs to set the "locals" dictionary to the class dict
when evaluating annotations defined inside a class namespace.
So this PEP defines a new ``__locals__`` attribute on
functions. By default it is uninitialized, or rather is set
to an internal value that indicates it hasn't been explicitly set.
It can be set to either ``None`` or a dictionary. If it's set to
a dictionary, the interpreter will use that dictionary as
the "locals" dictionary when running the function.

In Python, function objects contain a reference to their own
``__globals__``. However, class objects aren't currently
defined as doing so in Python. The implementation of
``__annotate__`` in CPython needs a reference to the module
globals in order to bind the unbound code object. So this PEP
defines a new ``__globals__`` attribute on class objects,
which stores a reference to the globals for the module where
the class was defined. Note that this attribute is optional,
but was useful for the CPython implementation.

(The class ``__globals__`` attribute does create a new reference
cycle, between a class and its module. However, any class that
contains a method already participates in at least one such cycle.)
This PEP does not dictate exactly how it should be
implemented; that is left up to the language implementation
maintainers. However, the best implementation of this this
PEP may require adding additional information to existing
Python objects, which is implicitly condoned by the acceptance
of this PEP.

For example, it may be necessary to add a
``__globals__`` attribute to class objects, so that the
``__annotate__`` function for that class can be lazily
bound, only on demand. Also, ``__annotate__`` functions
defined on methods defined in a class may need to retain
a reference to the class's ``__dict__``, in order to
correctly evaluate names bound in that class. It's expected
that the CPython implementation of this PEP will include
both those new attributes.

All such new information added to existing Python objects
should be done with "dunder" attributes, as they will of
course be implementation details.


Interactive REPL Shell
Expand Down