Skip to content

Commit 4173320

Browse files
bpo-41805: Documentation for PEP 585 (GH-22615)
1 parent 35b95aa commit 4173320

File tree

4 files changed

+211
-0
lines changed

4 files changed

+211
-0
lines changed

Doc/glossary.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,13 @@ Glossary
483483
See also the :term:`single dispatch` glossary entry, the
484484
:func:`functools.singledispatch` decorator, and :pep:`443`.
485485

486+
generic type
487+
A :term:`type` that can be parameterized; typically a container like
488+
:class:`list`. Used for :term:`type hints <type hint>` and
489+
:term:`annotations <annotation>`.
490+
491+
See :pep:`483` for more details, and :mod:`typing` or
492+
:ref:`generic alias type <types-genericalias>` for its uses.
486493

487494
GIL
488495
See :term:`global interpreter lock`.

Doc/library/stdtypes.rst

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4763,6 +4763,200 @@ define these methods must provide them as a normal Python accessible method.
47634763
Compared to the overhead of setting up the runtime context, the overhead of a
47644764
single class dictionary lookup is negligible.
47654765

4766+
4767+
.. _types-genericalias:
4768+
4769+
Generic Alias Type
4770+
==================
4771+
4772+
.. index::
4773+
object: GenericAlias
4774+
pair: Generic; Alias
4775+
4776+
``GenericAlias`` objects are created by subscripting a class (usually a
4777+
container), such as ``list[int]``. They are intended primarily for
4778+
:term:`type annotations <annotation>`.
4779+
4780+
Usually, the :ref:`subscription <subscriptions>` of container objects calls the
4781+
method :meth:`__getitem__` of the object. However, the subscription of some
4782+
containers' classes may call the classmethod :meth:`__class_getitem__` of the
4783+
class instead. The classmethod :meth:`__class_getitem__` should return a
4784+
``GenericAlias`` object.
4785+
4786+
.. note::
4787+
If the :meth:`__getitem__` of the class' metaclass is present, it will take
4788+
precedence over the :meth:`__class_getitem__` defined in the class (see
4789+
:pep:`560` for more details).
4790+
4791+
The ``GenericAlias`` object acts as a proxy for :term:`generic types
4792+
<generic type>`, implementing *parameterized generics* - a specific instance
4793+
of a generic which provides the types for container elements.
4794+
4795+
The user-exposed type for the ``GenericAlias`` object can be accessed from
4796+
:data:`types.GenericAlias` and used for :func:`isinstance` checks.
4797+
4798+
.. describe:: T[X, Y, ...]
4799+
4800+
Creates a ``GenericAlias`` representing a type ``T`` containing elements
4801+
of types *X*, *Y*, and more depending on the ``T`` used.
4802+
For example, a function expecting a :class:`list` containing
4803+
:class:`float` elements::
4804+
4805+
def average(values: list[float]) -> float:
4806+
return sum(values) / len(values)
4807+
4808+
Another example for :term:`mapping` objects, using a :class:`dict`, which
4809+
is a generic type expecting two type parameters representing the key type
4810+
and the value type. In this example, the function expects a ``dict`` with
4811+
keys of type :class:`str` and values of type :class:`int`::
4812+
4813+
def send_post_request(url: str, body: dict[str, int]) -> None:
4814+
...
4815+
4816+
The builtin functions :func:`isinstance` and :func:`issubclass` do not accept
4817+
``GenericAlias`` types for their second argument::
4818+
4819+
>>> isinstance([1, 2], list[str])
4820+
Traceback (most recent call last):
4821+
File "<stdin>", line 1, in <module>
4822+
TypeError: isinstance() argument 2 cannot be a parameterized generic
4823+
4824+
The Python runtime does not enforce :term:`type annotations <annotation>`.
4825+
This extends to generic types and their type parameters. When creating
4826+
an object from a ``GenericAlias``, container elements are not checked
4827+
against their type. For example, the following code is discouraged, but will
4828+
run without errors::
4829+
4830+
>>> t = list[str]
4831+
>>> t([1, 2, 3])
4832+
[1, 2, 3]
4833+
4834+
Furthermore, parameterized generics erase type parameters during object
4835+
creation::
4836+
4837+
>>> t = list[str]
4838+
>>> type(t)
4839+
<class 'types.GenericAlias'>
4840+
4841+
>>> l = t()
4842+
>>> type(l)
4843+
<class 'list'>
4844+
4845+
Calling :func:`repr` or :func:`str` on a generic shows the parameterized type::
4846+
4847+
>>> repr(list[int])
4848+
'list[int]'
4849+
4850+
>>> str(list[int])
4851+
'list[int]'
4852+
4853+
The :meth:`__getitem__` method of generics will raise an exception to disallow
4854+
mistakes like ``dict[str][str]``::
4855+
4856+
>>> dict[str][str]
4857+
Traceback (most recent call last):
4858+
File "<stdin>", line 1, in <module>
4859+
TypeError: There are no type variables left in dict[str]
4860+
4861+
However, such expressions are valid when :ref:`type variables <generics>` are
4862+
used. The index must have as many elements as there are type variable items
4863+
in the ``GenericAlias`` object's :attr:`__args__ <genericalias.__args__>`. ::
4864+
4865+
>>> from typing import TypeVar
4866+
>>> Y = TypeVar('Y')
4867+
>>> dict[str, Y][int]
4868+
dict[str, int]
4869+
4870+
4871+
Standard Generic Collections
4872+
----------------------------
4873+
4874+
These standard library collections support parameterized generics.
4875+
4876+
* :class:`tuple`
4877+
* :class:`list`
4878+
* :class:`dict`
4879+
* :class:`set`
4880+
* :class:`frozenset`
4881+
* :class:`type`
4882+
* :class:`collections.deque`
4883+
* :class:`collections.defaultdict`
4884+
* :class:`collections.OrderedDict`
4885+
* :class:`collections.Counter`
4886+
* :class:`collections.ChainMap`
4887+
* :class:`collections.abc.Awaitable`
4888+
* :class:`collections.abc.Coroutine`
4889+
* :class:`collections.abc.AsyncIterable`
4890+
* :class:`collections.abc.AsyncIterator`
4891+
* :class:`collections.abc.AsyncGenerator`
4892+
* :class:`collections.abc.Iterable`
4893+
* :class:`collections.abc.Iterator`
4894+
* :class:`collections.abc.Generator`
4895+
* :class:`collections.abc.Reversible`
4896+
* :class:`collections.abc.Container`
4897+
* :class:`collections.abc.Collection`
4898+
* :class:`collections.abc.Callable`
4899+
* :class:`collections.abc.Set`
4900+
* :class:`collections.abc.MutableSet`
4901+
* :class:`collections.abc.Mapping`
4902+
* :class:`collections.abc.MutableMapping`
4903+
* :class:`collections.abc.Sequence`
4904+
* :class:`collections.abc.MutableSequence`
4905+
* :class:`collections.abc.ByteString`
4906+
* :class:`collections.abc.MappingView`
4907+
* :class:`collections.abc.KeysView`
4908+
* :class:`collections.abc.ItemsView`
4909+
* :class:`collections.abc.ValuesView`
4910+
* :class:`contextlib.AbstractContextManager`
4911+
* :class:`contextlib.AbstractAsyncContextManager`
4912+
* :ref:`re.Pattern <re-objects>`
4913+
* :ref:`re.Match <match-objects>`
4914+
4915+
4916+
Special Attributes of Generic Alias
4917+
-----------------------------------
4918+
4919+
All parameterized generics implement special read-only attributes.
4920+
4921+
.. attribute:: genericalias.__origin__
4922+
4923+
This attribute points at the non-parameterized generic class::
4924+
4925+
>>> list[int].__origin__
4926+
<class 'list'>
4927+
4928+
4929+
.. attribute:: genericalias.__args__
4930+
4931+
This attribute is a :class:`tuple` (possibly of length 1) of generic
4932+
types passed to the original :meth:`__class_getitem__`
4933+
of the generic container::
4934+
4935+
>>> dict[str, list[int]].__args__
4936+
(<class 'str'>, list[int])
4937+
4938+
4939+
.. attribute:: genericalias.__parameters__
4940+
4941+
This attribute is a lazily computed tuple (possibly empty) of unique type
4942+
variables found in ``__args__``::
4943+
4944+
>>> from typing import TypeVar
4945+
4946+
>>> T = TypeVar('T')
4947+
>>> list[T].__parameters__
4948+
(~T,)
4949+
4950+
4951+
.. seealso::
4952+
4953+
* :pep:`585` -- "Type Hinting Generics In Standard Collections"
4954+
* :meth:`__class_getitem__` -- Used to implement parameterized generics.
4955+
* :ref:`generics` -- Generics in the :mod:`typing` module.
4956+
4957+
.. versionadded:: 3.9
4958+
4959+
47664960
.. _types-union:
47674961

47684962
Union Type

Doc/library/types.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,13 @@ Standard names are defined for the following types:
262262

263263
.. versionadded:: 3.10
264264

265+
.. data:: GenericAlias
266+
267+
The type of :ref:`parameterized generics <types-genericalias>` such as
268+
``list[int]``.
269+
270+
.. versionadded:: 3.9
271+
265272
.. data:: Union
266273

267274
The type of :ref:`union type expressions<types-union>`.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Documented :ref:`generic alias type <types-genericalias>` and
2+
:data:`types.GenericAlias`. Also added an entry in glossary for
3+
:term:`generic types <generic type>`.

0 commit comments

Comments
 (0)