summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/glossary.rst20
-rw-r--r--Doc/howto/annotations.rst21
-rw-r--r--Doc/library/__future__.rst14
-rw-r--r--Doc/library/annotationlib.rst349
-rw-r--r--Doc/library/inspect.rst69
-rw-r--r--Doc/library/python.rst1
-rw-r--r--Doc/library/typing.rst111
-rw-r--r--Doc/reference/compound_stmts.rst46
-rw-r--r--Doc/reference/datamodel.rst104
-rw-r--r--Doc/reference/executionmodel.rst23
-rw-r--r--Doc/reference/simple_stmts.rst26
11 files changed, 680 insertions, 104 deletions
diff --git a/Doc/glossary.rst b/Doc/glossary.rst
index d9f9392..ea2f4da 100644
--- a/Doc/glossary.rst
+++ b/Doc/glossary.rst
@@ -36,6 +36,12 @@ 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,
@@ -43,12 +49,11 @@ Glossary
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.
@@ -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,
diff --git a/Doc/howto/annotations.rst b/Doc/howto/annotations.rst
index be8c7e6..e9fc563 100644
--- a/Doc/howto/annotations.rst
+++ b/Doc/howto/annotations.rst
@@ -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
@@ -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.
@@ -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)``).
diff --git a/Doc/library/__future__.rst b/Doc/library/__future__.rst
index 1ebff44..6a11794 100644
--- a/Doc/library/__future__.rst
+++ b/Doc/library/__future__.rst
@@ -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.
@@ -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/python-dev@python.org/message/CLVXXPQ2T2LQ5MP2Y53VVQFCXYWQJHKZ/>`__;
- `announcement for Python 3.11 <https://mail.python.org/archives/list/python-dev@python.org/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::
diff --git a/Doc/library/annotationlib.rst b/Doc/library/annotationlib.rst
new file mode 100644
index 0000000..ecf56ed
--- /dev/null
+++ b/Doc/library/annotationlib.rst
@@ -0,0 +1,349 @@
+:mod:`!annotationlib` --- Functionality for introspecting annotations
+=====================================================================
+
+.. module:: annotationlib
+ :synopsis: Functionality for introspecting annotations
+
+
+**Source code:** :source:`Lib/annotationlib.py`
+
+.. testsetup:: default
+
+ import annotationlib
+ from annotationlib import *
+
+--------------
+
+The :mod:`!annotationlib` module provides tools for introspecting
+:term:`annotations <annotation>` on modules, classes, and functions.
+
+Annotations are :ref:`lazily evaluated <lazy-evaluation>` and often contain
+forward references to objects that are not yet defined when the annotation
+is created. This module provides a set of low-level tools that can be used to retrieve annotations in a reliable way, even
+in the presence of forward references and other edge cases.
+
+This module supports retrieving annotations in three main formats
+(see :class:`Format`), each of which works best for different use cases:
+
+* :attr:`~Format.VALUE` evaluates the annotations and returns their value.
+ This is most straightforward to work with, but it may raise errors,
+ for example if the annotations contain references to undefined names.
+* :attr:`~Format.FORWARDREF` returns :class:`ForwardRef` objects
+ for annotations that cannot be resolved, allowing you to inspect the
+ annotations without evaluating them. This is useful when you need to
+ work with annotations that may contain unresolved forward references.
+* :attr:`~Format.SOURCE` returns the annotations as a string, similar
+ to how it would appear in the source file. This is useful for documentation
+ generators that want to display annotations in a readable way.
+
+The :func:`get_annotations` function is the main entry point for
+retrieving annotations. Given a function, class, or module, it returns
+an annotations dictionary in the requested format. This module also provides
+functionality for working directly with the :term:`annotate function`
+that is used to evaluate annotations, such as :func:`get_annotate_function`
+and :func:`call_annotate_function`, as well as the
+:func:`call_evaluate_function` function for working with
+:term:`evaluate functions <evaluate function>`.
+
+
+.. seealso::
+
+ :pep:`649` proposed the current model for how annotations work in Python.
+
+ :pep:`749` expanded on various aspects of :pep:`649` and introduced the
+ :mod:`!annotationlib` module.
+
+ :ref:`annotations-howto` provides best practices for working with
+ annotations.
+
+ :pypi:`typing-extensions` provides a backport of :func:`get_annotations`
+ that works on earlier versions of Python.
+
+Annotation semantics
+--------------------
+
+The way annotations are evaluated has changed over the history of Python 3,
+and currently still depends on a :ref:`future import <future>`.
+There have been execution models for annotations:
+
+* *Stock semantics* (default in Python 3.0 through 3.13; see :pep:`3107`
+ and :pep:`526`): Annotations are evaluated eagerly, as they are
+ encountered in the source code.
+* *Stringified annotations* (used with ``from __future__ import annotations``
+ in Python 3.7 and newer; see :pep:`563`): Annotations are stored as
+ strings only.
+* *Deferred evaluation* (default in Python 3.14 and newer; see :pep:`649` and
+ :pep:`749`): Annotations are evaluated lazily, only when they are accessed.
+
+As an example, consider the following program::
+
+ def func(a: Cls) -> None:
+ print(a)
+
+ class Cls: pass
+
+ print(func.__annotations__)
+
+This will behave as follows:
+
+* Under stock semantics (Python 3.13 and earlier), it will throw a
+ :exc:`NameError` at the line where ``func`` is defined,
+ because ``Cls`` is an undefined name at that point.
+* Under stringified annotations (if ``from __future__ import annotations``
+ is used), it will print ``{'a': 'Cls', 'return': 'None'}``.
+* Under deferred evaluation (Python 3.14 and later), it will print
+ ``{'a': <class 'Cls'>, 'return': None}``.
+
+Stock semantics were used when function annotations were first introduced
+in Python 3.0 (by :pep:`3107`) because this was the simplest, most obvious
+way to implement annotations. The same execution model was used when variable
+annotations were introduced in Python 3.6 (by :pep:`526`). However,
+stock semantics caused problems when using annotations as type hints,
+such as a need to refer to names that are not yet defined when the
+annotation is encountered. In addition, there were performance problems
+with executing annotations at module import time. Therefore, in Python 3.7,
+:pep:`563` introduced the ability to store annotations as strings using the
+``from __future__ import annotations`` syntax. The plan at the time was to
+eventually make this behavior the default, but a problem appeared:
+stringified annotations are more difficult to process for those who
+introspect annotations at runtime. An alternative proposal, :pep:`649`,
+introduced the third execution model, deferred evaluation, and was implemented
+in Python 3.14. Stringified annotations are still used if
+``from __future__ import annotations`` is present, but this behavior will
+eventually be removed.
+
+Classes
+-------
+
+.. class:: Format
+
+ An :class:`~enum.IntEnum` describing the formats in which annotations
+ can be returned. Members of the enum, or their equivalent integer values,
+ can be passed to :func:`get_annotations` and other functions in this
+ module, as well as to :attr:`~object.__annotate__` functions.
+
+ .. attribute:: VALUE
+ :value: 1
+
+ Values are the result of evaluating the annotation expressions.
+
+ .. attribute:: FORWARDREF
+ :value: 2
+
+ Values are real annotation values (as per :attr:`Format.VALUE` format)
+ for defined values, and :class:`ForwardRef` proxies for undefined
+ values. Real objects may contain references to, :class:`ForwardRef`
+ proxy objects.
+
+ .. attribute:: SOURCE
+ :value: 3
+
+ Values are the text string of the annotation as it appears in the
+ source code, up to modifications including, but not restricted to,
+ whitespace normalizations and constant values optimizations.
+
+ The exact values of these strings may change in future versions of Python.
+
+ .. versionadded:: 3.14
+
+.. class:: ForwardRef
+
+ A proxy object for forward references in annotations.
+
+ Instances of this class are returned when the :attr:`~Format.FORWARDREF`
+ format is used and annotations contain a name that cannot be resolved.
+ This can happen when a forward reference is used in an annotation, such as
+ when a class is referenced before it is defined.
+
+ .. attribute:: __forward_arg__
+
+ A string containing the code that was evaluated to produce the
+ :class:`~ForwardRef`. The string may not be exactly equivalent
+ to the original source.
+
+ .. method:: evaluate(*, globals=None, locals=None, type_params=None, owner=None)
+
+ Evaluate the forward reference, returning its value.
+
+ This may throw an exception, such as :exc:`NameError`, if the forward
+ reference refers to names that do not exist. The arguments to this
+ method can be used to provide bindings for names that would otherwise
+ be undefined.
+
+ :class:`~ForwardRef` instances returned by :func:`get_annotations`
+ retain references to information about the scope they originated from,
+ so calling this method with no further arguments may be sufficient to
+ evaluate such objects. :class:`~ForwardRef` instances created by other
+ means may not have any information about their scope, so passing
+ arguments to this method may be necessary to evaluate them successfully.
+
+ *globals* and *locals* are passed to :func:`eval`, representing
+ the global and local namespaces in which the name is evaluated.
+ *type_params*, if given, must be a tuple of
+ :ref:`type parameters <type-params>` that are in scope while the forward
+ reference is being evaluated. *owner* is the object that owns the
+ annotation from which the forward reference derives, usually a function,
+ class, or module.
+
+ .. important::
+
+ Once a :class:`~ForwardRef` instance has been evaluated, it caches
+ the evaluated value, and future calls to :meth:`evaluate` will return
+ the cached value, regardless of the parameters passed in.
+
+ .. versionadded:: 3.14
+
+
+Functions
+---------
+
+.. function:: call_annotate_function(annotate, format, *, owner=None)
+
+ Call the :term:`annotate function` *annotate* with the given *format*,
+ a member of the :class:`Format` enum, and return the annotations
+ dictionary produced by the function.
+
+ This helper function is required because annotate functions generated by
+ the compiler for functions, classes, and modules only support
+ the :attr:`~Format.VALUE` format when called directly.
+ To support other formats, this function calls the annotate function
+ in a special environment that allows it to produce annotations in the
+ other formats. This is a useful building block when implementing
+ functionality that needs to partially evaluate annotations while a class
+ is being constructed.
+
+ *owner* is the object that owns the annotation function, usually
+ a function, class, or module. If provided, it is used in the
+ :attr:`~Format.FORWARDREF` format to produce a :class:`ForwardRef`
+ object that carries more information.
+
+ .. seealso::
+
+ :PEP:`PEP 649 <649#the-stringizer-and-the-fake-globals-environment>`
+ contains an explanation of the implementation technique used by this
+ function.
+
+ .. versionadded:: 3.14
+
+.. function:: call_evaluate_function(evaluate, format, *, owner=None)
+
+ Call the :term:`evaluate function` *evaluate* with the given *format*,
+ a member of the :class:`Format` enum, and return the value produced by
+ the function. This is similar to :func:`call_annotate_function`,
+ but the latter always returns a dictionary mapping strings to annotations,
+ while this function returns a single value.
+
+ This is intended for use with the evaluate functions generated for lazily
+ evaluated elements related to type aliases and type parameters:
+
+ * :meth:`typing.TypeAliasType.evaluate_value`, the value of type aliases
+ * :meth:`typing.TypeVar.evaluate_bound`, the bound of type variables
+ * :meth:`typing.TypeVar.evaluate_constraints`, the constraints of
+ type variables
+ * :meth:`typing.TypeVar.evaluate_default`, the default value of
+ type variables
+ * :meth:`typing.ParamSpec.evaluate_default`, the default value of
+ parameter specifications
+ * :meth:`typing.TypeVarTuple.evaluate_default`, the default value of
+ type variable tuples
+
+ *owner* is the object that owns the evaluate function, such as the type
+ alias or type variable object.
+
+ *format* can be used to control the format in which the value is returned:
+
+ .. doctest::
+
+ >>> type Alias = undefined
+ >>> call_evaluate_function(Alias.evaluate_value, Format.VALUE)
+ Traceback (most recent call last):
+ ...
+ NameError: name 'undefined' is not defined
+ >>> call_evaluate_function(Alias.evaluate_value, Format.FORWARDREF)
+ ForwardRef('undefined')
+ >>> call_evaluate_function(Alias.evaluate_value, Format.SOURCE)
+ 'undefined'
+
+ .. versionadded:: 3.14
+
+.. function:: get_annotate_function(obj)
+
+ Retrieve the :term:`annotate function` for *obj*. Return :const:`!None`
+ if *obj* does not have an annotate function.
+
+ This is usually equivalent to accessing the :attr:`~object.__annotate__`
+ attribute of *obj*, but direct access to the attribute may return the wrong
+ object in certain situations involving metaclasses. This function should be
+ used instead of accessing the attribute directly.
+
+ .. versionadded:: 3.14
+
+.. function:: get_annotations(obj, *, globals=None, locals=None, eval_str=False, format=Format.VALUE)
+
+ Compute the annotations dict for an object.
+
+ *obj* may be a callable, class, module, or other object with
+ :attr:`~object.__annotate__` and :attr:`~object.__annotations__` attributes.
+ Passing in an object of any other type raises :exc:`TypeError`.
+
+ The *format* parameter controls the format in which annotations are returned,
+ and must be a member of the :class:`Format` enum or its integer equivalent.
+
+ Returns a dict. :func:`!get_annotations` returns a new dict every time
+ it's called; calling it twice on the same object will return two
+ different but equivalent dicts.
+
+ This function handles several details for you:
+
+ * If *eval_str* is true, values of type :class:`!str` will
+ be un-stringized using :func:`eval`. This is intended
+ for use with stringized annotations
+ (``from __future__ import annotations``). It is an error
+ to set *eval_str* to true with formats other than :attr:`Format.VALUE`.
+ * If *obj* doesn't have an annotations dict, returns an
+ empty dict. (Functions and methods always have an
+ annotations dict; classes, modules, and other types of
+ callables may not.)
+ * Ignores inherited annotations on classes, as well as annotations
+ on metaclasses. If a class
+ doesn't have its own annotations dict, returns an empty dict.
+ * All accesses to object members and dict values are done
+ using ``getattr()`` and ``dict.get()`` for safety.
+
+ *eval_str* controls whether or not values of type :class:`!str` are
+ replaced with the result of calling :func:`eval` on those values:
+
+ * If eval_str is true, :func:`eval` is called on values of type
+ :class:`!str`. (Note that :func:`!get_annotations` doesn't catch
+ exceptions; if :func:`eval()` raises an exception, it will unwind
+ the stack past the :func:`!get_annotations` call.)
+ * If *eval_str* is false (the default), values of type :class:`!str` are
+ unchanged.
+
+ *globals* and *locals* are passed in to :func:`eval`; see the documentation
+ for :func:`eval` for more information. If *globals* or *locals*
+ is :const:`!None`, this function may replace that value with a
+ context-specific default, contingent on ``type(obj)``:
+
+ * If *obj* is a module, *globals* defaults to ``obj.__dict__``.
+ * If *obj* is a class, *globals* defaults to
+ ``sys.modules[obj.__module__].__dict__`` and *locals* defaults
+ to the *obj* class namespace.
+ * If *obj* is a callable, *globals* defaults to
+ :attr:`obj.__globals__ <function.__globals__>`,
+ although if *obj* is a wrapped function (using
+ :func:`functools.update_wrapper`) or a :class:`functools.partial` object,
+ it is unwrapped until a non-wrapped function is found.
+
+ Calling :func:`!get_annotations` is best practice for accessing the
+ annotations dict of any object. See :ref:`annotations-howto` for
+ more information on annotations best practices.
+
+ .. doctest::
+
+ >>> def f(a: int, b: str) -> float:
+ ... pass
+ >>> get_annotations(f)
+ {'a': <class 'int'>, 'b': <class 'str'>, 'return': <class 'float'>}
+
+ .. versionadded:: 3.14
diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst
index d19e779..f55824a 100644
--- a/Doc/library/inspect.rst
+++ b/Doc/library/inspect.rst
@@ -718,19 +718,19 @@ function.
Accepts a wide range of Python callables, from plain functions and classes to
:func:`functools.partial` objects.
- For objects defined in modules using stringized annotations
- (``from __future__ import annotations``), :func:`signature` will
+ If some of the annotations are strings (e.g., because
+ ``from __future__ import annotations`` was used), :func:`signature` will
attempt to automatically un-stringize the annotations using
- :func:`get_annotations`. The
+ :func:`annotationlib.get_annotations`. The
*globals*, *locals*, and *eval_str* parameters are passed
- into :func:`get_annotations` when resolving the
- annotations; see the documentation for :func:`get_annotations`
+ into :func:`!annotationlib.get_annotations` when resolving the
+ annotations; see the documentation for :func:`!annotationlib.get_annotations`
for instructions on how to use these parameters.
Raises :exc:`ValueError` if no signature can be provided, and
:exc:`TypeError` if that type of object is not supported. Also,
if the annotations are stringized, and *eval_str* is not false,
- the ``eval()`` call(s) to un-stringize the annotations in :func:`get_annotations`
+ the ``eval()`` call(s) to un-stringize the annotations in :func:`annotationlib.get_annotations`
could potentially raise any kind of exception.
A slash(/) in the signature of a function denotes that the parameters prior
@@ -1247,62 +1247,19 @@ Classes and functions
.. versionadded:: 3.4
-.. function:: get_annotations(obj, *, globals=None, locals=None, eval_str=False)
+.. function:: get_annotations(obj, *, globals=None, locals=None, eval_str=False, format=annotationlib.Format.VALUE)
Compute the annotations dict for an object.
- ``obj`` may be a callable, class, or module.
- Passing in an object of any other type raises :exc:`TypeError`.
-
- Returns a dict. ``get_annotations()`` returns a new dict every time
- it's called; calling it twice on the same object will return two
- different but equivalent dicts.
-
- This function handles several details for you:
-
- * If ``eval_str`` is true, values of type ``str`` will
- be un-stringized using :func:`eval`. This is intended
- for use with stringized annotations
- (``from __future__ import annotations``).
- * If ``obj`` doesn't have an annotations dict, returns an
- empty dict. (Functions and methods always have an
- annotations dict; classes, modules, and other types of
- callables may not.)
- * Ignores inherited annotations on classes. If a class
- doesn't have its own annotations dict, returns an empty dict.
- * All accesses to object members and dict values are done
- using ``getattr()`` and ``dict.get()`` for safety.
- * Always, always, always returns a freshly created dict.
-
- ``eval_str`` controls whether or not values of type ``str`` are replaced
- with the result of calling :func:`eval` on those values:
-
- * If eval_str is true, :func:`eval` is called on values of type ``str``.
- (Note that ``get_annotations`` doesn't catch exceptions; if :func:`eval`
- raises an exception, it will unwind the stack past the ``get_annotations``
- call.)
- * If eval_str is false (the default), values of type ``str`` are unchanged.
-
- ``globals`` and ``locals`` are passed in to :func:`eval`; see the documentation
- for :func:`eval` for more information. If ``globals`` or ``locals``
- is ``None``, this function may replace that value with a context-specific
- default, contingent on ``type(obj)``:
-
- * If ``obj`` is a module, ``globals`` defaults to ``obj.__dict__``.
- * If ``obj`` is a class, ``globals`` defaults to
- ``sys.modules[obj.__module__].__dict__`` and ``locals`` defaults
- to the ``obj`` class namespace.
- * If ``obj`` is a callable, ``globals`` defaults to
- :attr:`obj.__globals__ <function.__globals__>`,
- although if ``obj`` is a wrapped function (using
- :func:`functools.update_wrapper`) it is first unwrapped.
-
- Calling ``get_annotations`` is best practice for accessing the
- annotations dict of any object. See :ref:`annotations-howto` for
- more information on annotations best practices.
+ This is an alias for :func:`annotationlib.get_annotations`; see the documentation
+ of that function for more information.
.. versionadded:: 3.10
+ .. versionchanged:: 3.14
+ This function is now an alias for :func:`annotationlib.get_annotations`.
+ Calling it as ``inspect.get_annotations`` will continue to work.
+
.. _inspect-stack:
diff --git a/Doc/library/python.rst b/Doc/library/python.rst
index 6104359..c2c231a 100644
--- a/Doc/library/python.rst
+++ b/Doc/library/python.rst
@@ -25,4 +25,5 @@ overview:
__future__.rst
gc.rst
inspect.rst
+ annotationlib.rst
site.rst
diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst
index f8b533a..cb5b46f 100644
--- a/Doc/library/typing.rst
+++ b/Doc/library/typing.rst
@@ -1825,6 +1825,16 @@ without the dedicated syntax, as documented below.
the bound is evaluated only when the attribute is accessed, not when
the type variable is created (see :ref:`lazy-evaluation`).
+ .. method:: evaluate_bound
+
+ An :term:`evaluate function` corresponding to the :attr:`~TypeVar.__bound__` attribute.
+ When called directly, this method supports only the :attr:`~annotationlib.Format.VALUE`
+ format, which is equivalent to accessing the :attr:`~TypeVar.__bound__` attribute directly,
+ but the method object can be passed to :func:`annotationlib.call_evaluate_function`
+ to evaluate the value in a different format.
+
+ .. versionadded:: 3.14
+
.. attribute:: __constraints__
A tuple containing the constraints of the type variable, if any.
@@ -1835,6 +1845,16 @@ without the dedicated syntax, as documented below.
the constraints are evaluated only when the attribute is accessed, not when
the type variable is created (see :ref:`lazy-evaluation`).
+ .. method:: evaluate_constraints
+
+ An :term:`evaluate function` corresponding to the :attr:`~TypeVar.__constraints__` attribute.
+ When called directly, this method supports only the :attr:`~annotationlib.Format.VALUE`
+ format, which is equivalent to accessing the :attr:`~TypeVar.__constraints__` attribute directly,
+ but the method object can be passed to :func:`annotationlib.call_evaluate_function`
+ to evaluate the value in a different format.
+
+ .. versionadded:: 3.14
+
.. attribute:: __default__
The default value of the type variable, or :data:`typing.NoDefault` if it
@@ -1842,6 +1862,16 @@ without the dedicated syntax, as documented below.
.. versionadded:: 3.13
+ .. method:: evaluate_default
+
+ An :term:`evaluate function` corresponding to the :attr:`~TypeVar.__default__` attribute.
+ When called directly, this method supports only the :attr:`~annotationlib.Format.VALUE`
+ format, which is equivalent to accessing the :attr:`~TypeVar.__default__` attribute directly,
+ but the method object can be passed to :func:`annotationlib.call_evaluate_function`
+ to evaluate the value in a different format.
+
+ .. versionadded:: 3.14
+
.. method:: has_default()
Return whether or not the type variable has a default value. This is equivalent
@@ -1980,6 +2010,16 @@ without the dedicated syntax, as documented below.
.. versionadded:: 3.13
+ .. method:: evaluate_default
+
+ An :term:`evaluate function` corresponding to the :attr:`~TypeVarTuple.__default__` attribute.
+ When called directly, this method supports only the :attr:`~annotationlib.Format.VALUE`
+ format, which is equivalent to accessing the :attr:`~TypeVarTuple.__default__` attribute directly,
+ but the method object can be passed to :func:`annotationlib.call_evaluate_function`
+ to evaluate the value in a different format.
+
+ .. versionadded:: 3.14
+
.. method:: has_default()
Return whether or not the type variable tuple has a default value. This is equivalent
@@ -2076,6 +2116,16 @@ without the dedicated syntax, as documented below.
.. versionadded:: 3.13
+ .. method:: evaluate_default
+
+ An :term:`evaluate function` corresponding to the :attr:`~ParamSpec.__default__` attribute.
+ When called directly, this method supports only the :attr:`~annotationlib.Format.VALUE`
+ format, which is equivalent to accessing the :attr:`~ParamSpec.__default__` attribute directly,
+ but the method object can be passed to :func:`annotationlib.call_evaluate_function`
+ to evaluate the value in a different format.
+
+ .. versionadded:: 3.14
+
.. method:: has_default()
Return whether or not the parameter specification has a default value. This is equivalent
@@ -2200,6 +2250,32 @@ without the dedicated syntax, as documented below.
>>> Recursive.__value__
Mutually
+ .. method:: evaluate_value
+
+ An :term:`evaluate function` corresponding to the :attr:`__value__` attribute.
+ When called directly, this method supports only the :attr:`~annotationlib.Format.VALUE`
+ format, which is equivalent to accessing the :attr:`__value__` attribute directly,
+ but the method object can be passed to :func:`annotationlib.call_evaluate_function`
+ to evaluate the value in a different format:
+
+ .. doctest::
+
+ >>> type Alias = undefined
+ >>> Alias.__value__
+ Traceback (most recent call last):
+ ...
+ NameError: name 'undefined' is not defined
+ >>> from annotationlib import Format, call_evaluate_function
+ >>> Alias.evaluate_value(Format.VALUE)
+ Traceback (most recent call last):
+ ...
+ NameError: name 'undefined' is not defined
+ >>> call_evaluate_function(Alias.evaluate_value, Format.FORWARDREF)
+ ForwardRef('undefined')
+
+ .. versionadded:: 3.14
+
+
Other special directives
""""""""""""""""""""""""
@@ -3306,7 +3382,7 @@ Introspection helpers
Class used for internal typing representation of string forward references.
For example, ``List["SomeClass"]`` is implicitly transformed into
- ``List[ForwardRef("SomeClass")]``. ``ForwardRef`` should not be instantiated by
+ ``List[ForwardRef("SomeClass")]``. :class:`!ForwardRef` should not be instantiated by
a user, but may be used by introspection tools.
.. note::
@@ -3316,6 +3392,39 @@ Introspection helpers
.. versionadded:: 3.7.4
+ .. versionchanged:: 3.14
+ This is now an alias for :class:`annotationlib.ForwardRef`.
+
+.. function:: evaluate_forward_ref(forward_ref, *, owner=None, globals=None, locals=None, type_params=None, format=annotationlib.Format.VALUE)
+
+ Evaluate an :class:`annotationlib.ForwardRef` as a :term:`type hint`.
+
+ This is similar to calling :meth:`annotationlib.ForwardRef.evaluate`,
+ but unlike that method, :func:`!evaluate_forward_ref` also:
+
+ * Recursively evaluates forward references nested within the type hint.
+ * Raises :exc:`TypeError` when it encounters certain objects that are
+ not valid type hints.
+ * Replaces type hints that evaluate to :const:`!None` with
+ :class:`types.NoneType`.
+ * Supports the :attr:`~annotationlib.Format.FORWARDREF` and
+ :attr:`~annotationlib.Format.SOURCE` formats.
+
+ *forward_ref* must be an instance of :class:`~annotationlib.ForwardRef`.
+ *owner*, if given, should be the object that holds the annotations that
+ the forward reference derived from, such as a module, class object, or function.
+ It is used to infer the namespaces to use for looking up names.
+ *globals* and *locals* can also be explicitly given to provide
+ the global and local namespaces.
+ *type_params* is a tuple of :ref:`type parameters <type-params>` that
+ are in scope when evaluating the forward reference.
+ This parameter must be provided (though it may be an empty tuple) if *owner*
+ is not given and the forward reference does not already have an owner set.
+ *format* specifies the format of the annotation and is a member of
+ the :class:`annotationlib.Format` enum.
+
+ .. versionadded:: 3.14
+
.. data:: NoDefault
A sentinel object used to indicate that a type parameter has no default
diff --git a/Doc/reference/compound_stmts.rst b/Doc/reference/compound_stmts.rst
index 46ee3a1..d31fbf8 100644
--- a/Doc/reference/compound_stmts.rst
+++ b/Doc/reference/compound_stmts.rst
@@ -1329,13 +1329,7 @@ following the parameter name. Any parameter may have an annotation, even those
``*identifier`` or ``**identifier``. Functions may have "return" annotation of
the form "``-> expression``" after the parameter list. These annotations can be
any valid Python expression. The presence of annotations does not change the
-semantics of a function. The annotation values are available as values of
-a dictionary keyed by the parameters' names in the :attr:`__annotations__`
-attribute of the function object. If the ``annotations`` import from
-:mod:`__future__` is used, annotations are preserved as strings at runtime which
-enables postponed evaluation. Otherwise, they are evaluated when the function
-definition is executed. In this case annotations may be evaluated in
-a different order than they appear in the source code.
+semantics of a function. See :ref:`annotations` for more information on annotations.
.. index:: pair: lambda; expression
@@ -1852,6 +1846,44 @@ Here, ``annotation-def`` (not a real keyword) indicates an
:ref:`annotation scope <annotation-scopes>`. The capitalized names
like ``TYPE_PARAMS_OF_ListOrSet`` are not actually bound at runtime.
+.. _annotations:
+
+Annotations
+===========
+
+.. versionchanged:: 3.14
+ Annotations are now lazily evaluated by default.
+
+Variables and function parameters may carry :term:`annotations <annotation>`,
+created by adding a colon after the name, followed by an expression::
+
+ x: annotation = 1
+ def f(param: annotation): ...
+
+Functions may also carry a return annotation following an arrow::
+
+ def f() -> annotation: ...
+
+Annotations are conventionally used for :term:`type hints <type hint>`, but this
+is not enforced by the language, and in general annotations may contain arbitrary
+expressions. The presence of annotations does not change the runtime semantics of
+the code, except if some mechanism is used that introspects and uses the annotations
+(such as :mod:`dataclasses` or :func:`functools.singledispatch`).
+
+By default, annotations are lazily evaluated in a :ref:`annotation scope <annotation-scopes>`.
+This means that they are not evaluated when the code containing the annotation is evaluated.
+Instead, the interpreter saves information that can be used to evaluate the annotation later
+if requested. The :mod:`annotationlib` module provides tools for evaluating annotations.
+
+If the :ref:`future statement <future>` ``from __future__ import annotations`` is present,
+all annotations are instead stored as strings::
+
+ >>> from __future__ import annotations
+ >>> def f(param: annotation): ...
+ >>> f.__annotations__
+ {'param': 'annotation'}
+
+
.. rubric:: Footnotes
.. [#] The exception is propagated to the invocation stack unless
diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst
index ee97038..21aee0b 100644
--- a/Doc/reference/datamodel.rst
+++ b/Doc/reference/datamodel.rst
@@ -581,6 +581,7 @@ Special writable attributes
single: __defaults__ (function attribute)
single: __code__ (function attribute)
single: __annotations__ (function attribute)
+ single: __annotate__ (function attribute)
single: __kwdefaults__ (function attribute)
single: __type_params__ (function attribute)
@@ -628,7 +629,17 @@ Most of these attributes check the type of the assigned value:
:term:`parameters <parameter>`.
The keys of the dictionary are the parameter names,
and ``'return'`` for the return annotation, if provided.
- See also: :ref:`annotations-howto`.
+ See also: :attr:`object.__annotations__`.
+
+ .. versionchanged:: 3.14
+ Annotations are now :ref:`lazily evaluated <lazy-evaluation>`.
+ See :pep:`649`.
+
+ * - .. attribute:: function.__annotate__
+ - The :term:`annotate function` for this function, or ``None``
+ if the function has no annotations. See :attr:`object.__annotate__`.
+
+ .. versionadded:: 3.14
* - .. attribute:: function.__kwdefaults__
- A :class:`dictionary <dict>` containing defaults for keyword-only
@@ -881,6 +892,7 @@ Attribute assignment updates the module's namespace dictionary, e.g.,
single: __doc__ (module attribute)
single: __file__ (module attribute)
single: __annotations__ (module attribute)
+ single: __annotate__ (module attribute)
pair: module; namespace
Predefined (writable) attributes:
@@ -901,11 +913,21 @@ Predefined (writable) attributes:
loaded dynamically from a shared library, it's the pathname of the shared
library file.
- :attr:`__annotations__`
+ :attr:`~object.__annotations__`
A dictionary containing
:term:`variable annotations <variable annotation>` collected during
module body execution. For best practices on working
- with :attr:`__annotations__`, please see :ref:`annotations-howto`.
+ with :attr:`!__annotations__`, see :mod:`annotationlib`.
+
+ .. versionchanged:: 3.14
+ Annotations are now :ref:`lazily evaluated <lazy-evaluation>`.
+ See :pep:`649`.
+
+ :attr:`~object.__annotate__`
+ The :term:`annotate function` for this module, or ``None``
+ if the module has no annotations. See :attr:`object.__annotate__`.
+
+ .. versionadded:: 3.14
.. index:: single: __dict__ (module attribute)
@@ -969,6 +991,7 @@ A class object can be called (see above) to yield a class instance (see below).
single: __bases__ (class attribute)
single: __doc__ (class attribute)
single: __annotations__ (class attribute)
+ single: __annotate__ (class attribute)
single: __type_params__ (class attribute)
single: __static_attributes__ (class attribute)
single: __firstlineno__ (class attribute)
@@ -991,12 +1014,36 @@ Special attributes:
:attr:`__doc__`
The class's documentation string, or ``None`` if undefined.
- :attr:`__annotations__`
+ :attr:`~object.__annotations__`
A dictionary containing
:term:`variable annotations <variable annotation>`
collected during class body execution. For best practices on
- working with :attr:`__annotations__`, please see
- :ref:`annotations-howto`.
+ working with :attr:`~object.__annotations__`, please see
+ :mod:`annotationlib`.
+
+ .. warning::
+
+ Accessing the :attr:`~object.__annotations__` attribute of a class
+ object directly may yield incorrect results in the presence of
+ metaclasses. Use :func:`annotationlib.get_annotations` to
+ retrieve class annotations safely.
+
+ .. versionchanged:: 3.14
+ Annotations are now :ref:`lazily evaluated <lazy-evaluation>`.
+ See :pep:`649`.
+
+ :attr:`~object.__annotate__`
+ The :term:`annotate function` for this class, or ``None``
+ if the class has no annotations. See :attr:`object.__annotate__`.
+
+ .. warning::
+
+ Accessing the :attr:`~object.__annotate__` attribute of a class
+ object directly may yield incorrect results in the presence of
+ metaclasses. Use :func:`annotationlib.get_annotate_function` to
+ retrieve the annotate function safely.
+
+ .. versionadded:: 3.14
:attr:`__type_params__`
A tuple containing the :ref:`type parameters <type-params>` of
@@ -3253,6 +3300,51 @@ implement the protocol in Python.
:class:`collections.abc.Buffer`
ABC for buffer types.
+Annotations
+-----------
+
+Functions, classes, and modules may contain :term:`annotations <annotation>`,
+which are a way to associate information (usually :term:`type hints <type hint>`)
+with a symbol.
+
+.. attribute:: object.__annotations__
+
+ This attribute contains the annotations for an object. It is
+ :ref:`lazily evaluated <lazy-evaluation>`, so accessing the attribute may
+ execute arbitrary code and raise exceptions. If evaluation is successful, the
+ attribute is set to a dictionary mapping from variable names to annotations.
+
+ .. versionchanged:: 3.14
+ Annotations are now lazily evaluated.
+
+.. method:: object.__annotate__(format)
+
+ An :term:`annotate function`.
+ Returns a new dictionary object mapping attribute/parameter names to their annotation values.
+
+ Takes a format parameter specifying the format in which annotations values should be provided.
+ It must be a member of the :class:`annotationlib.Format` enum, or an integer with
+ a value corresponding to a member of the enum.
+
+ If an annotate function doesn't support the requested format, it must raise
+ :exc:`NotImplementedError`. Annotate functions must always support
+ :attr:`~annotationlib.Format.VALUE` format; they must not raise
+ :exc:`NotImplementedError()` when called with this format.
+
+ When called with :attr:`~annotationlib.Format.VALUE` format, an annotate function may raise
+ :exc:`NameError`; it must not raise :exc:`!NameError` when called requesting any other format.
+
+ If an object does not have any annotations, :attr:`~object.__annotate__` should preferably be set
+ to ``None`` (it can’t be deleted), rather than set to a function that returns an empty dict.
+
+ .. versionadded:: 3.14
+
+.. seealso::
+
+ :pep:`649` --- Deferred evaluation of annotation using descriptors
+ Introduces lazy evaluation of annotations and the ``__annotate__`` function.
+
+
.. _special-lookup:
Special method lookup
diff --git a/Doc/reference/executionmodel.rst b/Doc/reference/executionmodel.rst
index f24e153..a02b515 100644
--- a/Doc/reference/executionmodel.rst
+++ b/Doc/reference/executionmodel.rst
@@ -190,14 +190,15 @@ However, the following will succeed::
Annotation scopes
-----------------
-:ref:`Type parameter lists <type-params>` and :keyword:`type` statements
+:term:`Annotations <annotation>`, :ref:`type parameter lists <type-params>`
+and :keyword:`type` statements
introduce *annotation scopes*, which behave mostly like function scopes,
-but with some exceptions discussed below. :term:`Annotations <annotation>`
-currently do not use annotation scopes, but they are expected to use
-annotation scopes in Python 3.13 when :pep:`649` is implemented.
+but with some exceptions discussed below.
Annotation scopes are used in the following contexts:
+* :term:`Function annotations <function annotation>`.
+* :term:`Variable annotations <variable annotation>`.
* Type parameter lists for :ref:`generic type aliases <generic-type-aliases>`.
* Type parameter lists for :ref:`generic functions <generic-functions>`.
A generic function's annotations are
@@ -236,17 +237,23 @@ Annotation scopes differ from function scopes in the following ways:
Annotation scopes are also used for type parameter defaults, as
introduced by :pep:`696`.
+.. versionchanged:: 3.14
+ Annotation scopes are now also used for annotations, as specified in
+ :pep:`649` and :pep:`749`.
+
.. _lazy-evaluation:
Lazy evaluation
---------------
-The values of type aliases created through the :keyword:`type` statement are
-*lazily evaluated*. The same applies to the bounds, constraints, and default values of type
+Most annotation scopes are *lazily evaluated*. This includes annotations,
+the values of type aliases created through the :keyword:`type` statement, and
+the bounds, constraints, and default values of type
variables created through the :ref:`type parameter syntax <type-params>`.
This means that they are not evaluated when the type alias or type variable is
-created. Instead, they are only evaluated when doing so is necessary to resolve
-an attribute access.
+created, or when the object carrying annotations is created. Instead, they
+are only evaluated when necessary, for example when the ``__value__``
+attribute on a type alias is accessed.
Example:
diff --git a/Doc/reference/simple_stmts.rst b/Doc/reference/simple_stmts.rst
index 618664b..24df4a6 100644
--- a/Doc/reference/simple_stmts.rst
+++ b/Doc/reference/simple_stmts.rst
@@ -336,23 +336,21 @@ The difference from normal :ref:`assignment` is that only a single target is all
The assignment target is considered "simple" if it consists of a single
name that is not enclosed in parentheses.
For simple assignment targets, if in class or module scope,
-the annotations are evaluated and stored in a special class or module
-attribute :attr:`__annotations__`
-that is a dictionary mapping from variable names (mangled if private) to
-evaluated annotations. This attribute is writable and is automatically
-created at the start of class or module body execution, if annotations
-are found statically.
+the annotations are gathered in a lazily evaluated
+:ref:`annotation scope <annotation-scopes>`. The annotations can be
+evaluated using the :attr:`~object.__annotations__` attribute of a
+class or module, or using the facilities in the :mod:`annotationlib`
+module.
If the assignment target is not simple (an attribute, subscript node, or
-parenthesized name), the annotation is evaluated if
-in class or module scope, but not stored.
+parenthesized name), the annotation is never evaluated.
If a name is annotated in a function scope, then this name is local for
that scope. Annotations are never evaluated and stored in function scopes.
If the right hand side is present, an annotated
-assignment performs the actual assignment before evaluating annotations
-(where applicable). If the right hand side is not present for an expression
+assignment performs the actual assignment as if there was no annotation
+present. If the right hand side is not present for an expression
target, then the interpreter evaluates the target except for the last
:meth:`~object.__setitem__` or :meth:`~object.__setattr__` call.
@@ -373,6 +371,10 @@ target, then the interpreter evaluates the target except for the last
regular assignments. Previously, some expressions (like un-parenthesized
tuple expressions) caused a syntax error.
+.. versionchanged:: 3.14
+ Annotations are now lazily evaluated in a separate :ref:`annotation scope <annotation-scopes>`.
+ If the assignment target is not simple, annotations are never evaluated.
+
.. _assert:
@@ -975,8 +977,8 @@ block textually preceding that :keyword:`!global` statement.
Names listed in a :keyword:`global` statement must not be defined as formal
parameters, or as targets in :keyword:`with` statements or :keyword:`except` clauses, or in a :keyword:`for` target list, :keyword:`class`
-definition, function definition, :keyword:`import` statement, or variable
-annotation.
+definition, function definition, :keyword:`import` statement, or
+:term:`variable annotations <variable annotation>`.
.. impl-detail::