Skip to content

Commit

Permalink
gh-119180: Documentation for PEP 649 and 749 (#122235)
Browse files Browse the repository at this point in the history
Co-authored-by: Bénédikt Tran <[email protected]>
Co-authored-by: Adam Turner <[email protected]>
Co-authored-by: Carol Willing <[email protected]>
  • Loading branch information
4 people committed Sep 11, 2024
1 parent 6e23c89 commit 5436d8b
Show file tree
Hide file tree
Showing 11 changed files with 680 additions and 104 deletions.
20 changes: 15 additions & 5 deletions Doc/glossary.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,24 @@ Glossary
and loaders (in the :mod:`importlib.abc` module). You can create your own
ABCs with the :mod:`abc` module.

annotate function
A function that can be called to retrieve the :term:`annotations <annotation>`
of an object. This function is accessible as the :attr:`~object.__annotate__`
attribute of functions, classes, and modules. Annotate functions are a
subset of :term:`evaluate functions <evaluate function>`.

annotation
A label associated with a variable, a class
attribute or a function parameter or return value,
used by convention as a :term:`type hint`.

Annotations of local variables cannot be accessed at runtime, but
annotations of global variables, class attributes, and functions
are stored in the :attr:`__annotations__`
special attribute of modules, classes, and functions,
respectively.
can be retrieved by calling :func:`annotationlib.get_annotations`
on modules, classes, and functions, respectively.

See :term:`variable annotation`, :term:`function annotation`, :pep:`484`
and :pep:`526`, which describe this functionality.
See :term:`variable annotation`, :term:`function annotation`, :pep:`484`,
:pep:`526`, and :pep:`649`, which describe this functionality.
Also see :ref:`annotations-howto`
for best practices on working with annotations.

Expand Down Expand Up @@ -366,6 +371,11 @@ Glossary
statements. The technique contrasts with the :term:`LBYL` style
common to many other languages such as C.

evaluate function
A function that can be called to evaluate a lazily evaluated attribute
of an object, such as the value of type aliases created with the :keyword:`type`
statement.

expression
A piece of syntax which can be evaluated to some value. In other words,
an expression is an accumulation of expression elements like literals,
Expand Down
21 changes: 19 additions & 2 deletions Doc/howto/annotations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,16 @@ Accessing The Annotations Dict Of An Object In Python 3.10 And Newer

Python 3.10 adds a new function to the standard library:
:func:`inspect.get_annotations`. In Python versions 3.10
and newer, calling this function is the best practice for
through 3.13, calling this function is the best practice for
accessing the annotations dict of any object that supports
annotations. This function can also "un-stringize"
stringized annotations for you.

In Python 3.14, there is a new :mod:`annotationlib` module
with functionality for working with annotations. This
includes a :func:`annotationlib.get_annotations` function,
which supersedes :func:`inspect.get_annotations`.

If for some reason :func:`inspect.get_annotations` isn't
viable for your use case, you may access the
``__annotations__`` data member manually. Best practice
Expand Down Expand Up @@ -184,7 +189,11 @@ Best Practices For ``__annotations__`` In Any Python Version
* If you do assign directly to the ``__annotations__`` member
of an object, you should always set it to a ``dict`` object.

* If you directly access the ``__annotations__`` member
* You should avoid accessing ``__annotations__`` directly on any object.
Instead, use :func:`annotationlib.get_annotations` (Python 3.14+)
or :func:`inspect.get_annotations` (Python 3.10+).

* If you do directly access the ``__annotations__`` member
of an object, you should ensure that it's a
dictionary before attempting to examine its contents.

Expand Down Expand Up @@ -231,3 +240,11 @@ itself be quoted. In effect the annotation is quoted

This prints ``{'a': "'str'"}``. This shouldn't really be considered
a "quirk"; it's mentioned here simply because it might be surprising.

If you use a class with a custom metaclass and access ``__annotations__``
on the class, you may observe unexpected behavior; see
:pep:`749 <749#pep749-metaclasses>` for some examples. You can avoid these
quirks by using :func:`annotationlib.get_annotations` on Python 3.14+ or
:func:`inspect.get_annotations` on Python 3.10+. On earlier versions of
Python, you can avoid these bugs by accessing the annotations from the
class's ``__dict__`` (e.g., ``cls.__dict__.get('__annotations__', None)``).
14 changes: 7 additions & 7 deletions Doc/library/__future__.rst
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,10 @@ language using this mechanism:
| generator_stop | 3.5.0b1 | 3.7 | :pep:`479`: |
| | | | *StopIteration handling inside generators* |
+------------------+-------------+--------------+---------------------------------------------+
| annotations | 3.7.0b1 | TBD [1]_ | :pep:`563`: |
| | | | *Postponed evaluation of annotations* |
| annotations | 3.7.0b1 | Never [1]_ | :pep:`563`: |
| | | | *Postponed evaluation of annotations*, |
| | | | :pep:`649`: *Deferred evalutation of |
| | | | annotations using descriptors* |
+------------------+-------------+--------------+---------------------------------------------+

.. XXX Adding a new entry? Remember to update simple_stmts.rst, too.
Expand Down Expand Up @@ -115,11 +117,9 @@ language using this mechanism:

.. [1]
``from __future__ import annotations`` was previously scheduled to
become mandatory in Python 3.10, but the Python Steering Council
twice decided to delay the change
(`announcement for Python 3.10 <https://mail.python.org/archives/list/[email protected]/message/CLVXXPQ2T2LQ5MP2Y53VVQFCXYWQJHKZ/>`__;
`announcement for Python 3.11 <https://mail.python.org/archives/list/[email protected]/message/VIZEBX5EYMSYIJNDBF6DMUMZOCWHARSO/>`__).
No final decision has been made yet. See also :pep:`563` and :pep:`649`.
become mandatory in Python 3.10, but the change was delayed and ultimately
canceled. This feature will eventually be deprecated and removed. See
:pep:`649` and :pep:`749`.
.. seealso::
Expand Down
Loading

0 comments on commit 5436d8b

Please sign in to comment.