mirror of https://github.com/python/cpython
gh-119180: Documentation for PEP 649 and 749 (#122235)
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Co-authored-by: Carol Willing <carolcode@willingconsulting.com>
This commit is contained in:
parent
6e23c89fcd
commit
5436d8b9c3
|
@ -36,6 +36,12 @@ Glossary
|
||||||
and loaders (in the :mod:`importlib.abc` module). You can create your own
|
and loaders (in the :mod:`importlib.abc` module). You can create your own
|
||||||
ABCs with the :mod:`abc` module.
|
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
|
annotation
|
||||||
A label associated with a variable, a class
|
A label associated with a variable, a class
|
||||||
attribute or a function parameter or return value,
|
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 local variables cannot be accessed at runtime, but
|
||||||
annotations of global variables, class attributes, and functions
|
annotations of global variables, class attributes, and functions
|
||||||
are stored in the :attr:`__annotations__`
|
can be retrieved by calling :func:`annotationlib.get_annotations`
|
||||||
special attribute of modules, classes, and functions,
|
on modules, classes, and functions, respectively.
|
||||||
respectively.
|
|
||||||
|
|
||||||
See :term:`variable annotation`, :term:`function annotation`, :pep:`484`
|
See :term:`variable annotation`, :term:`function annotation`, :pep:`484`,
|
||||||
and :pep:`526`, which describe this functionality.
|
:pep:`526`, and :pep:`649`, which describe this functionality.
|
||||||
Also see :ref:`annotations-howto`
|
Also see :ref:`annotations-howto`
|
||||||
for best practices on working with annotations.
|
for best practices on working with annotations.
|
||||||
|
|
||||||
|
@ -366,6 +371,11 @@ Glossary
|
||||||
statements. The technique contrasts with the :term:`LBYL` style
|
statements. The technique contrasts with the :term:`LBYL` style
|
||||||
common to many other languages such as C.
|
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
|
expression
|
||||||
A piece of syntax which can be evaluated to some value. In other words,
|
A piece of syntax which can be evaluated to some value. In other words,
|
||||||
an expression is an accumulation of expression elements like literals,
|
an expression is an accumulation of expression elements like literals,
|
||||||
|
|
|
@ -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:
|
Python 3.10 adds a new function to the standard library:
|
||||||
:func:`inspect.get_annotations`. In Python versions 3.10
|
: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
|
accessing the annotations dict of any object that supports
|
||||||
annotations. This function can also "un-stringize"
|
annotations. This function can also "un-stringize"
|
||||||
stringized annotations for you.
|
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
|
If for some reason :func:`inspect.get_annotations` isn't
|
||||||
viable for your use case, you may access the
|
viable for your use case, you may access the
|
||||||
``__annotations__`` data member manually. Best practice
|
``__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
|
* If you do assign directly to the ``__annotations__`` member
|
||||||
of an object, you should always set it to a ``dict`` object.
|
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
|
of an object, you should ensure that it's a
|
||||||
dictionary before attempting to examine its contents.
|
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
|
This prints ``{'a': "'str'"}``. This shouldn't really be considered
|
||||||
a "quirk"; it's mentioned here simply because it might be surprising.
|
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)``).
|
||||||
|
|
|
@ -64,8 +64,10 @@ language using this mechanism:
|
||||||
| generator_stop | 3.5.0b1 | 3.7 | :pep:`479`: |
|
| generator_stop | 3.5.0b1 | 3.7 | :pep:`479`: |
|
||||||
| | | | *StopIteration handling inside generators* |
|
| | | | *StopIteration handling inside generators* |
|
||||||
+------------------+-------------+--------------+---------------------------------------------+
|
+------------------+-------------+--------------+---------------------------------------------+
|
||||||
| annotations | 3.7.0b1 | TBD [1]_ | :pep:`563`: |
|
| annotations | 3.7.0b1 | Never [1]_ | :pep:`563`: |
|
||||||
| | | | *Postponed evaluation of annotations* |
|
| | | | *Postponed evaluation of annotations*, |
|
||||||
|
| | | | :pep:`649`: *Deferred evalutation of |
|
||||||
|
| | | | annotations using descriptors* |
|
||||||
+------------------+-------------+--------------+---------------------------------------------+
|
+------------------+-------------+--------------+---------------------------------------------+
|
||||||
|
|
||||||
.. XXX Adding a new entry? Remember to update simple_stmts.rst, too.
|
.. XXX Adding a new entry? Remember to update simple_stmts.rst, too.
|
||||||
|
@ -115,11 +117,9 @@ language using this mechanism:
|
||||||
|
|
||||||
.. [1]
|
.. [1]
|
||||||
``from __future__ import annotations`` was previously scheduled to
|
``from __future__ import annotations`` was previously scheduled to
|
||||||
become mandatory in Python 3.10, but the Python Steering Council
|
become mandatory in Python 3.10, but the change was delayed and ultimately
|
||||||
twice decided to delay the change
|
canceled. This feature will eventually be deprecated and removed. See
|
||||||
(`announcement for Python 3.10 <https://mail.python.org/archives/list/python-dev@python.org/message/CLVXXPQ2T2LQ5MP2Y53VVQFCXYWQJHKZ/>`__;
|
:pep:`649` and :pep:`749`.
|
||||||
`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`.
|
|
||||||
|
|
||||||
|
|
||||||
.. seealso::
|
.. seealso::
|
||||||
|
|
|
@ -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
|
|
@ -718,19 +718,19 @@ function.
|
||||||
Accepts a wide range of Python callables, from plain functions and classes to
|
Accepts a wide range of Python callables, from plain functions and classes to
|
||||||
:func:`functools.partial` objects.
|
:func:`functools.partial` objects.
|
||||||
|
|
||||||
For objects defined in modules using stringized annotations
|
If some of the annotations are strings (e.g., because
|
||||||
(``from __future__ import annotations``), :func:`signature` will
|
``from __future__ import annotations`` was used), :func:`signature` will
|
||||||
attempt to automatically un-stringize the annotations using
|
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
|
*globals*, *locals*, and *eval_str* parameters are passed
|
||||||
into :func:`get_annotations` when resolving the
|
into :func:`!annotationlib.get_annotations` when resolving the
|
||||||
annotations; see the documentation for :func:`get_annotations`
|
annotations; see the documentation for :func:`!annotationlib.get_annotations`
|
||||||
for instructions on how to use these parameters.
|
for instructions on how to use these parameters.
|
||||||
|
|
||||||
Raises :exc:`ValueError` if no signature can be provided, and
|
Raises :exc:`ValueError` if no signature can be provided, and
|
||||||
:exc:`TypeError` if that type of object is not supported. Also,
|
:exc:`TypeError` if that type of object is not supported. Also,
|
||||||
if the annotations are stringized, and *eval_str* is not false,
|
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.
|
could potentially raise any kind of exception.
|
||||||
|
|
||||||
A slash(/) in the signature of a function denotes that the parameters prior
|
A slash(/) in the signature of a function denotes that the parameters prior
|
||||||
|
@ -1247,62 +1247,19 @@ Classes and functions
|
||||||
.. versionadded:: 3.4
|
.. 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.
|
Compute the annotations dict for an object.
|
||||||
|
|
||||||
``obj`` may be a callable, class, or module.
|
This is an alias for :func:`annotationlib.get_annotations`; see the documentation
|
||||||
Passing in an object of any other type raises :exc:`TypeError`.
|
of that function for more information.
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
.. versionadded:: 3.10
|
.. 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:
|
.. _inspect-stack:
|
||||||
|
|
||||||
|
|
|
@ -25,4 +25,5 @@ overview:
|
||||||
__future__.rst
|
__future__.rst
|
||||||
gc.rst
|
gc.rst
|
||||||
inspect.rst
|
inspect.rst
|
||||||
|
annotationlib.rst
|
||||||
site.rst
|
site.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 bound is evaluated only when the attribute is accessed, not when
|
||||||
the type variable is created (see :ref:`lazy-evaluation`).
|
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__
|
.. attribute:: __constraints__
|
||||||
|
|
||||||
A tuple containing the constraints of the type variable, if any.
|
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 constraints are evaluated only when the attribute is accessed, not when
|
||||||
the type variable is created (see :ref:`lazy-evaluation`).
|
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__
|
.. attribute:: __default__
|
||||||
|
|
||||||
The default value of the type variable, or :data:`typing.NoDefault` if it
|
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
|
.. 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()
|
.. method:: has_default()
|
||||||
|
|
||||||
Return whether or not the type variable has a default value. This is equivalent
|
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
|
.. 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()
|
.. method:: has_default()
|
||||||
|
|
||||||
Return whether or not the type variable tuple has a default value. This is equivalent
|
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
|
.. 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()
|
.. method:: has_default()
|
||||||
|
|
||||||
Return whether or not the parameter specification has a default value. This is equivalent
|
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__
|
>>> Recursive.__value__
|
||||||
Mutually
|
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
|
Other special directives
|
||||||
""""""""""""""""""""""""
|
""""""""""""""""""""""""
|
||||||
|
|
||||||
|
@ -3306,7 +3382,7 @@ Introspection helpers
|
||||||
Class used for internal typing representation of string forward references.
|
Class used for internal typing representation of string forward references.
|
||||||
|
|
||||||
For example, ``List["SomeClass"]`` is implicitly transformed into
|
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.
|
a user, but may be used by introspection tools.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
@ -3316,6 +3392,39 @@ Introspection helpers
|
||||||
|
|
||||||
.. versionadded:: 3.7.4
|
.. 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
|
.. data:: NoDefault
|
||||||
|
|
||||||
A sentinel object used to indicate that a type parameter has no default
|
A sentinel object used to indicate that a type parameter has no default
|
||||||
|
|
|
@ -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
|
``*identifier`` or ``**identifier``. Functions may have "return" annotation of
|
||||||
the form "``-> expression``" after the parameter list. These annotations can be
|
the form "``-> expression``" after the parameter list. These annotations can be
|
||||||
any valid Python expression. The presence of annotations does not change the
|
any valid Python expression. The presence of annotations does not change the
|
||||||
semantics of a function. The annotation values are available as values of
|
semantics of a function. See :ref:`annotations` for more information on annotations.
|
||||||
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.
|
|
||||||
|
|
||||||
.. index:: pair: lambda; expression
|
.. 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
|
:ref:`annotation scope <annotation-scopes>`. The capitalized names
|
||||||
like ``TYPE_PARAMS_OF_ListOrSet`` are not actually bound at runtime.
|
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
|
.. rubric:: Footnotes
|
||||||
|
|
||||||
.. [#] The exception is propagated to the invocation stack unless
|
.. [#] The exception is propagated to the invocation stack unless
|
||||||
|
|
|
@ -581,6 +581,7 @@ Special writable attributes
|
||||||
single: __defaults__ (function attribute)
|
single: __defaults__ (function attribute)
|
||||||
single: __code__ (function attribute)
|
single: __code__ (function attribute)
|
||||||
single: __annotations__ (function attribute)
|
single: __annotations__ (function attribute)
|
||||||
|
single: __annotate__ (function attribute)
|
||||||
single: __kwdefaults__ (function attribute)
|
single: __kwdefaults__ (function attribute)
|
||||||
single: __type_params__ (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>`.
|
:term:`parameters <parameter>`.
|
||||||
The keys of the dictionary are the parameter names,
|
The keys of the dictionary are the parameter names,
|
||||||
and ``'return'`` for the return annotation, if provided.
|
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__
|
* - .. attribute:: function.__kwdefaults__
|
||||||
- A :class:`dictionary <dict>` containing defaults for keyword-only
|
- 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: __doc__ (module attribute)
|
||||||
single: __file__ (module attribute)
|
single: __file__ (module attribute)
|
||||||
single: __annotations__ (module attribute)
|
single: __annotations__ (module attribute)
|
||||||
|
single: __annotate__ (module attribute)
|
||||||
pair: module; namespace
|
pair: module; namespace
|
||||||
|
|
||||||
Predefined (writable) attributes:
|
Predefined (writable) attributes:
|
||||||
|
@ -901,11 +913,21 @@ Predefined (writable) attributes:
|
||||||
loaded dynamically from a shared library, it's the pathname of the shared
|
loaded dynamically from a shared library, it's the pathname of the shared
|
||||||
library file.
|
library file.
|
||||||
|
|
||||||
:attr:`__annotations__`
|
:attr:`~object.__annotations__`
|
||||||
A dictionary containing
|
A dictionary containing
|
||||||
:term:`variable annotations <variable annotation>` collected during
|
:term:`variable annotations <variable annotation>` collected during
|
||||||
module body execution. For best practices on working
|
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)
|
.. 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: __bases__ (class attribute)
|
||||||
single: __doc__ (class attribute)
|
single: __doc__ (class attribute)
|
||||||
single: __annotations__ (class attribute)
|
single: __annotations__ (class attribute)
|
||||||
|
single: __annotate__ (class attribute)
|
||||||
single: __type_params__ (class attribute)
|
single: __type_params__ (class attribute)
|
||||||
single: __static_attributes__ (class attribute)
|
single: __static_attributes__ (class attribute)
|
||||||
single: __firstlineno__ (class attribute)
|
single: __firstlineno__ (class attribute)
|
||||||
|
@ -991,12 +1014,36 @@ Special attributes:
|
||||||
:attr:`__doc__`
|
:attr:`__doc__`
|
||||||
The class's documentation string, or ``None`` if undefined.
|
The class's documentation string, or ``None`` if undefined.
|
||||||
|
|
||||||
:attr:`__annotations__`
|
:attr:`~object.__annotations__`
|
||||||
A dictionary containing
|
A dictionary containing
|
||||||
:term:`variable annotations <variable annotation>`
|
:term:`variable annotations <variable annotation>`
|
||||||
collected during class body execution. For best practices on
|
collected during class body execution. For best practices on
|
||||||
working with :attr:`__annotations__`, please see
|
working with :attr:`~object.__annotations__`, please see
|
||||||
:ref:`annotations-howto`.
|
: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__`
|
:attr:`__type_params__`
|
||||||
A tuple containing the :ref:`type parameters <type-params>` of
|
A tuple containing the :ref:`type parameters <type-params>` of
|
||||||
|
@ -3253,6 +3300,51 @@ implement the protocol in Python.
|
||||||
:class:`collections.abc.Buffer`
|
:class:`collections.abc.Buffer`
|
||||||
ABC for buffer types.
|
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-lookup:
|
||||||
|
|
||||||
Special method lookup
|
Special method lookup
|
||||||
|
|
|
@ -190,14 +190,15 @@ However, the following will succeed::
|
||||||
Annotation scopes
|
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,
|
introduce *annotation scopes*, which behave mostly like function scopes,
|
||||||
but with some exceptions discussed below. :term:`Annotations <annotation>`
|
but with some exceptions discussed below.
|
||||||
currently do not use annotation scopes, but they are expected to use
|
|
||||||
annotation scopes in Python 3.13 when :pep:`649` is implemented.
|
|
||||||
|
|
||||||
Annotation scopes are used in the following contexts:
|
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 type aliases <generic-type-aliases>`.
|
||||||
* Type parameter lists for :ref:`generic functions <generic-functions>`.
|
* Type parameter lists for :ref:`generic functions <generic-functions>`.
|
||||||
A generic function's annotations are
|
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
|
Annotation scopes are also used for type parameter defaults, as
|
||||||
introduced by :pep:`696`.
|
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:
|
||||||
|
|
||||||
Lazy evaluation
|
Lazy evaluation
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
The values of type aliases created through the :keyword:`type` statement are
|
Most annotation scopes are *lazily evaluated*. This includes annotations,
|
||||||
*lazily evaluated*. The same applies to the bounds, constraints, and default values of type
|
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>`.
|
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
|
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
|
created, or when the object carrying annotations is created. Instead, they
|
||||||
an attribute access.
|
are only evaluated when necessary, for example when the ``__value__``
|
||||||
|
attribute on a type alias is accessed.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
|
|
|
@ -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
|
The assignment target is considered "simple" if it consists of a single
|
||||||
name that is not enclosed in parentheses.
|
name that is not enclosed in parentheses.
|
||||||
For simple assignment targets, if in class or module scope,
|
For simple assignment targets, if in class or module scope,
|
||||||
the annotations are evaluated and stored in a special class or module
|
the annotations are gathered in a lazily evaluated
|
||||||
attribute :attr:`__annotations__`
|
:ref:`annotation scope <annotation-scopes>`. The annotations can be
|
||||||
that is a dictionary mapping from variable names (mangled if private) to
|
evaluated using the :attr:`~object.__annotations__` attribute of a
|
||||||
evaluated annotations. This attribute is writable and is automatically
|
class or module, or using the facilities in the :mod:`annotationlib`
|
||||||
created at the start of class or module body execution, if annotations
|
module.
|
||||||
are found statically.
|
|
||||||
|
|
||||||
If the assignment target is not simple (an attribute, subscript node, or
|
If the assignment target is not simple (an attribute, subscript node, or
|
||||||
parenthesized name), the annotation is evaluated if
|
parenthesized name), the annotation is never evaluated.
|
||||||
in class or module scope, but not stored.
|
|
||||||
|
|
||||||
If a name is annotated in a function scope, then this name is local for
|
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.
|
that scope. Annotations are never evaluated and stored in function scopes.
|
||||||
|
|
||||||
If the right hand side is present, an annotated
|
If the right hand side is present, an annotated
|
||||||
assignment performs the actual assignment before evaluating annotations
|
assignment performs the actual assignment as if there was no annotation
|
||||||
(where applicable). If the right hand side is not present for an expression
|
present. If the right hand side is not present for an expression
|
||||||
target, then the interpreter evaluates the target except for the last
|
target, then the interpreter evaluates the target except for the last
|
||||||
:meth:`~object.__setitem__` or :meth:`~object.__setattr__` call.
|
: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
|
regular assignments. Previously, some expressions (like un-parenthesized
|
||||||
tuple expressions) caused a syntax error.
|
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:
|
.. _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
|
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`
|
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
|
definition, function definition, :keyword:`import` statement, or
|
||||||
annotation.
|
:term:`variable annotations <variable annotation>`.
|
||||||
|
|
||||||
.. impl-detail::
|
.. impl-detail::
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue