Skip to content

Commit

Permalink
More documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
JelleZijlstra committed Jul 27, 2024
1 parent c82fb66 commit b4f6385
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 8 deletions.
8 changes: 7 additions & 1 deletion Doc/glossary.rst
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ Glossary
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.
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
Expand Down Expand Up @@ -370,6 +371,11 @@ Glossary
statements. The technique contrasts with the :term:`LBYL` style
common to many other languages such as C.

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

expression
A piece of syntax which can be evaluated to some value. In other words,
an expression is an accumulation of expression elements like literals,
Expand Down
48 changes: 42 additions & 6 deletions Doc/library/annotationlib.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,52 @@ on modules, classes, and 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.
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.

Annotate functions generated by the compiler for functions, classes, and modules support only
the :attr:`~Format.VALUE` format when called directly. This function calls the annotate function
in a special environment that allows it to produce annotations in the other formats.
Annotate functions generated by the compiler for functions, classes,
and modules support only the :attr:`~Format.VALUE` format when called
directly. This function calls the annotate function in a special
environment that allows it to produce annotations in the other formats.

*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 carry more information.
object that carries more information.

.. 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)
...
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

Expand Down
74 changes: 74 additions & 0 deletions Doc/library/typing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1744,6 +1744,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.
Expand All @@ -1754,13 +1764,33 @@ 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
has no default.

.. 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
Expand Down Expand Up @@ -1899,6 +1929,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
Expand Down Expand Up @@ -1995,6 +2035,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
Expand Down Expand Up @@ -2119,6 +2169,30 @@ 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__
...
NameError: name 'undefined' is not defined
>>> from annotationlib import Format, call_evaluate_function
>>> Alias.evaluate_value(Format.VALUE)
...
NameError: name 'undefined' is not defined
>>> call_evaluate_function(Alias.evaluate_value, Format.FORWARDREF)
ForwardRef('undefined')

.. versionadded:: 3.14


Other special directives
""""""""""""""""""""""""

Expand Down
2 changes: 1 addition & 1 deletion Lib/annotationlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import sys
import types

__all__ = ["Format", "ForwardRef", "call_annotate_function", "get_annotations"]
__all__ = ["Format", "ForwardRef", "call_annotate_function", "call_evaluate_function", "get_annotate_function", "get_annotations"]


class Format(enum.IntEnum):
Expand Down

0 comments on commit b4f6385

Please sign in to comment.