diff options
| author | kj <28750310+Fidget-Spinner@users.noreply.github.com> | 2020-10-28 15:33:36 (GMT) |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-10-28 15:33:36 (GMT) |
| commit | 577d7c4e628260eb7926d043ca9c355ece583eb7 (patch) | |
| tree | d2549bf9a6f34f30533bad2e6908fc6f78bf72d5 | |
| parent | 24a7c298d47658295673dc04d1b6d59f2b200a7c (diff) | |
| download | cpython-577d7c4e628260eb7926d043ca9c355ece583eb7.zip cpython-577d7c4e628260eb7926d043ca9c355ece583eb7.tar.gz cpython-577d7c4e628260eb7926d043ca9c355ece583eb7.tar.bz2 | |
[3.9] bpo-41805: Documentation for PEP 585 (GH-22615) (GH-23016)
Backport of #22615 to 3.9 since that couldn't be auto-merged due to conflicts.
| -rw-r--r-- | Doc/glossary.rst | 7 | ||||
| -rw-r--r-- | Doc/library/stdtypes.rst | 193 | ||||
| -rw-r--r-- | Doc/library/types.rst | 8 | ||||
| -rw-r--r-- | Misc/NEWS.d/next/Documentation/2020-10-10-01-36-37.bpo-41805.l-CGv5.rst | 3 |
4 files changed, 211 insertions, 0 deletions
diff --git a/Doc/glossary.rst b/Doc/glossary.rst index 847500e..4fd01e0 100644 --- a/Doc/glossary.rst +++ b/Doc/glossary.rst @@ -483,6 +483,13 @@ Glossary See also the :term:`single dispatch` glossary entry, the :func:`functools.singledispatch` decorator, and :pep:`443`. + generic type + A :term:`type` that can be parameterized; typically a container like + :class:`list`. Used for :term:`type hints <type hint>` and + :term:`annotations <annotation>`. + + See :pep:`483` for more details, and :mod:`typing` or + :ref:`generic alias type <types-genericalias>` for its uses. GIL See :term:`global interpreter lock`. diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 1de48e1..e19e76f 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -4731,6 +4731,199 @@ Compared to the overhead of setting up the runtime context, the overhead of a single class dictionary lookup is negligible. +.. _types-genericalias: + +Generic Alias Type +================== + +.. index:: + object: GenericAlias + pair: Generic; Alias + +``GenericAlias`` objects are created by subscripting a class (usually a +container), such as ``list[int]``. They are intended primarily for +:term:`type annotations <annotation>`. + +Usually, the :ref:`subscription <subscriptions>` of container objects calls the +method :meth:`__getitem__` of the object. However, the subscription of some +containers' classes may call the classmethod :meth:`__class_getitem__` of the +class instead. The classmethod :meth:`__class_getitem__` should return a +``GenericAlias`` object. + +.. note:: + If the :meth:`__getitem__` of the class' metaclass is present, it will take + precedence over the :meth:`__class_getitem__` defined in the class (see + :pep:`560` for more details). + +The ``GenericAlias`` object acts as a proxy for :term:`generic types +<generic type>`, implementing *parameterized generics* - a specific instance +of a generic which provides the types for container elements. + +The user-exposed type for the ``GenericAlias`` object can be accessed from +:data:`types.GenericAlias` and used for :func:`isinstance` checks. + +.. describe:: T[X, Y, ...] + + Creates a ``GenericAlias`` representing a type ``T`` containing elements + of types *X*, *Y*, and more depending on the ``T`` used. + For example, a function expecting a :class:`list` containing + :class:`float` elements:: + + def average(values: list[float]) -> float: + return sum(values) / len(values) + + Another example for :term:`mapping` objects, using a :class:`dict`, which + is a generic type expecting two type parameters representing the key type + and the value type. In this example, the function expects a ``dict`` with + keys of type :class:`str` and values of type :class:`int`:: + + def send_post_request(url: str, body: dict[str, int]) -> None: + ... + +The builtin functions :func:`isinstance` and :func:`issubclass` do not accept +``GenericAlias`` types for their second argument:: + + >>> isinstance([1, 2], list[str]) + Traceback (most recent call last): + File "<stdin>", line 1, in <module> + TypeError: isinstance() argument 2 cannot be a parameterized generic + +The Python runtime does not enforce :term:`type annotations <annotation>`. +This extends to generic types and their type parameters. When creating +an object from a ``GenericAlias``, container elements are not checked +against their type. For example, the following code is discouraged, but will +run without errors:: + + >>> t = list[str] + >>> t([1, 2, 3]) + [1, 2, 3] + +Furthermore, parameterized generics erase type parameters during object +creation:: + + >>> t = list[str] + >>> type(t) + <class 'types.GenericAlias'> + + >>> l = t() + >>> type(l) + <class 'list'> + +Calling :func:`repr` or :func:`str` on a generic shows the parameterized type:: + + >>> repr(list[int]) + 'list[int]' + + >>> str(list[int]) + 'list[int]' + +The :meth:`__getitem__` method of generics will raise an exception to disallow +mistakes like ``dict[str][str]``:: + + >>> dict[str][str] + Traceback (most recent call last): + File "<stdin>", line 1, in <module> + TypeError: There are no type variables left in dict[str] + +However, such expressions are valid when :ref:`type variables <generics>` are +used. The index must have as many elements as there are type variable items +in the ``GenericAlias`` object's :attr:`__args__ <genericalias.__args__>`. :: + + >>> from typing import TypeVar + >>> Y = TypeVar('Y') + >>> dict[str, Y][int] + dict[str, int] + + +Standard Generic Collections +---------------------------- + +These standard library collections support parameterized generics. + +* :class:`tuple` +* :class:`list` +* :class:`dict` +* :class:`set` +* :class:`frozenset` +* :class:`type` +* :class:`collections.deque` +* :class:`collections.defaultdict` +* :class:`collections.OrderedDict` +* :class:`collections.Counter` +* :class:`collections.ChainMap` +* :class:`collections.abc.Awaitable` +* :class:`collections.abc.Coroutine` +* :class:`collections.abc.AsyncIterable` +* :class:`collections.abc.AsyncIterator` +* :class:`collections.abc.AsyncGenerator` +* :class:`collections.abc.Iterable` +* :class:`collections.abc.Iterator` +* :class:`collections.abc.Generator` +* :class:`collections.abc.Reversible` +* :class:`collections.abc.Container` +* :class:`collections.abc.Collection` +* :class:`collections.abc.Callable` +* :class:`collections.abc.Set` +* :class:`collections.abc.MutableSet` +* :class:`collections.abc.Mapping` +* :class:`collections.abc.MutableMapping` +* :class:`collections.abc.Sequence` +* :class:`collections.abc.MutableSequence` +* :class:`collections.abc.ByteString` +* :class:`collections.abc.MappingView` +* :class:`collections.abc.KeysView` +* :class:`collections.abc.ItemsView` +* :class:`collections.abc.ValuesView` +* :class:`contextlib.AbstractContextManager` +* :class:`contextlib.AbstractAsyncContextManager` +* :ref:`re.Pattern <re-objects>` +* :ref:`re.Match <match-objects>` + + +Special Attributes of Generic Alias +----------------------------------- + +All parameterized generics implement special read-only attributes. + +.. attribute:: genericalias.__origin__ + + This attribute points at the non-parameterized generic class:: + + >>> list[int].__origin__ + <class 'list'> + + +.. attribute:: genericalias.__args__ + + This attribute is a :class:`tuple` (possibly of length 1) of generic + types passed to the original :meth:`__class_getitem__` + of the generic container:: + + >>> dict[str, list[int]].__args__ + (<class 'str'>, list[int]) + + +.. attribute:: genericalias.__parameters__ + + This attribute is a lazily computed tuple (possibly empty) of unique type + variables found in ``__args__``:: + + >>> from typing import TypeVar + + >>> T = TypeVar('T') + >>> list[T].__parameters__ + (~T,) + + +.. seealso:: + + * :pep:`585` -- "Type Hinting Generics In Standard Collections" + * :meth:`__class_getitem__` -- Used to implement parameterized generics. + * :ref:`generics` -- Generics in the :mod:`typing` module. + +.. versionadded:: 3.9 + + .. _typesother: Other Built-in Types diff --git a/Doc/library/types.rst b/Doc/library/types.rst index a88e882..1573e46 100644 --- a/Doc/library/types.rst +++ b/Doc/library/types.rst @@ -242,6 +242,14 @@ Standard names are defined for the following types: Defaults to ``None``. Previously the attribute was optional. +.. data:: GenericAlias + + The type of :ref:`parameterized generics <types-genericalias>` such as + ``list[int]``. + + .. versionadded:: 3.9 + + .. class:: TracebackType(tb_next, tb_frame, tb_lasti, tb_lineno) The type of traceback objects such as found in ``sys.exc_info()[2]``. diff --git a/Misc/NEWS.d/next/Documentation/2020-10-10-01-36-37.bpo-41805.l-CGv5.rst b/Misc/NEWS.d/next/Documentation/2020-10-10-01-36-37.bpo-41805.l-CGv5.rst new file mode 100644 index 0000000..9c91343 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2020-10-10-01-36-37.bpo-41805.l-CGv5.rst @@ -0,0 +1,3 @@ +Documented :ref:`generic alias type <types-genericalias>` and +:data:`types.GenericAlias`. Also added an entry in glossary for +:term:`generic types <generic type>`. |
