typing docs: Move some classes out of the "Generics" section (#104707)

- AnyStr can be used in type annotations, contrary to the section header
- Unpack can also be used in annotations, and its use is not restricted
  to generics. It makes more sense with other building blocks like Required.
- Protocol is not necessarily generic.

Also fix the indentation for two notes associated with Concatenate.

Split off from #104642, but I think this change is independently an
improvement.
This commit is contained in:
Jelle Zijlstra 2023-05-21 06:00:50 -07:00 committed by GitHub
parent b9fcfa6024
commit ab71acd67b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 146 additions and 146 deletions

View File

@ -616,6 +616,21 @@ These can be used as types in annotations and do not support ``[]``.
avoiding type checker errors with classes that can duck type anywhere or
are highly dynamic.
.. data:: AnyStr
``AnyStr`` is a :ref:`constrained type variable <typing-constrained-typevar>` defined as
``AnyStr = TypeVar('AnyStr', str, bytes)``.
It is meant to be used for functions that may accept any kind of string
without allowing different kinds of strings to mix. For example::
def concat(a: AnyStr, b: AnyStr) -> AnyStr:
return a + b
concat(u"foo", u"bar") # Ok, output has type 'unicode'
concat(b"foo", b"bar") # Ok, output has type 'bytes'
concat(u"foo", b"bar") # Error, cannot mix unicode and bytes
.. data:: LiteralString
Special type that includes only literal strings. A string
@ -917,13 +932,13 @@ These can be used as types in annotations using ``[]``, each having a unique syn
# We don't need to pass in the lock ourselves thanks to the decorator.
sum_threadsafe([1.1, 2.2, 3.3])
.. versionadded:: 3.10
.. versionadded:: 3.10
.. seealso::
.. seealso::
* :pep:`612` -- Parameter Specification Variables (the PEP which introduced
``ParamSpec`` and ``Concatenate``).
* :class:`ParamSpec` and :class:`Callable`.
* :pep:`612` -- Parameter Specification Variables (the PEP which introduced
``ParamSpec`` and ``Concatenate``).
* :class:`ParamSpec` and :class:`Callable`.
.. class:: Type(Generic[CT_co])
@ -1208,6 +1223,49 @@ These can be used as types in annotations using ``[]``, each having a unique syn
.. versionadded:: 3.10
.. data:: Unpack
A typing operator that conceptually marks an object as having been
unpacked. For example, using the unpack operator ``*`` on a
:class:`type variable tuple <TypeVarTuple>` is equivalent to using ``Unpack``
to mark the type variable tuple as having been unpacked::
Ts = TypeVarTuple('Ts')
tup: tuple[*Ts]
# Effectively does:
tup: tuple[Unpack[Ts]]
In fact, ``Unpack`` can be used interchangeably with ``*`` in the context
of :class:`typing.TypeVarTuple <TypeVarTuple>` and
:class:`builtins.tuple <tuple>` types. You might see ``Unpack`` being used
explicitly in older versions of Python, where ``*`` couldn't be used in
certain places::
# In older versions of Python, TypeVarTuple and Unpack
# are located in the `typing_extensions` backports package.
from typing_extensions import TypeVarTuple, Unpack
Ts = TypeVarTuple('Ts')
tup: tuple[*Ts] # Syntax error on Python <= 3.10!
tup: tuple[Unpack[Ts]] # Semantically equivalent, and backwards-compatible
``Unpack`` can also be used along with :class:`typing.TypedDict` for typing
``**kwargs`` in a function signature::
from typing import TypedDict, Unpack
class Movie(TypedDict):
name: str
year: int
# This function expects two keyword arguments - `name` of type `str`
# and `year` of type `int`.
def foo(**kwargs: Unpack[Movie]): ...
See :pep:`692` for more details on using ``Unpack`` for ``**kwargs`` typing.
.. versionadded:: 3.11
Building generic types
""""""""""""""""""""""
@ -1409,49 +1467,6 @@ These are not used in annotations. They are building blocks for creating generic
.. versionadded:: 3.11
.. data:: Unpack
A typing operator that conceptually marks an object as having been
unpacked. For example, using the unpack operator ``*`` on a
:class:`type variable tuple <TypeVarTuple>` is equivalent to using ``Unpack``
to mark the type variable tuple as having been unpacked::
Ts = TypeVarTuple('Ts')
tup: tuple[*Ts]
# Effectively does:
tup: tuple[Unpack[Ts]]
In fact, ``Unpack`` can be used interchangeably with ``*`` in the context
of :class:`typing.TypeVarTuple <TypeVarTuple>` and
:class:`builtins.tuple <tuple>` types. You might see ``Unpack`` being used
explicitly in older versions of Python, where ``*`` couldn't be used in
certain places::
# In older versions of Python, TypeVarTuple and Unpack
# are located in the `typing_extensions` backports package.
from typing_extensions import TypeVarTuple, Unpack
Ts = TypeVarTuple('Ts')
tup: tuple[*Ts] # Syntax error on Python <= 3.10!
tup: tuple[Unpack[Ts]] # Semantically equivalent, and backwards-compatible
``Unpack`` can also be used along with :class:`typing.TypedDict` for typing
``**kwargs`` in a function signature::
from typing import TypedDict, Unpack
class Movie(TypedDict):
name: str
year: int
# This function expects two keyword arguments - `name` of type `str`
# and `year` of type `int`.
def foo(**kwargs: Unpack[Movie]): ...
See :pep:`692` for more details on using ``Unpack`` for ``**kwargs`` typing.
.. versionadded:: 3.11
.. class:: ParamSpec(name, *, bound=None, covariant=False, contravariant=False)
Parameter specification variable. A specialized version of
@ -1550,20 +1565,93 @@ These are not used in annotations. They are building blocks for creating generic
.. versionadded:: 3.10
.. data:: AnyStr
Other special directives
""""""""""""""""""""""""
``AnyStr`` is a :ref:`constrained type variable <typing-constrained-typevar>` defined as
``AnyStr = TypeVar('AnyStr', str, bytes)``.
These are not used in annotations. They are building blocks for declaring types.
It is meant to be used for functions that may accept any kind of string
without allowing different kinds of strings to mix. For example::
.. class:: NamedTuple
def concat(a: AnyStr, b: AnyStr) -> AnyStr:
return a + b
Typed version of :func:`collections.namedtuple`.
concat(u"foo", u"bar") # Ok, output has type 'unicode'
concat(b"foo", b"bar") # Ok, output has type 'bytes'
concat(u"foo", b"bar") # Error, cannot mix unicode and bytes
Usage::
class Employee(NamedTuple):
name: str
id: int
This is equivalent to::
Employee = collections.namedtuple('Employee', ['name', 'id'])
To give a field a default value, you can assign to it in the class body::
class Employee(NamedTuple):
name: str
id: int = 3
employee = Employee('Guido')
assert employee.id == 3
Fields with a default value must come after any fields without a default.
The resulting class has an extra attribute ``__annotations__`` giving a
dict that maps the field names to the field types. (The field names are in
the ``_fields`` attribute and the default values are in the
``_field_defaults`` attribute, both of which are part of the :func:`~collections.namedtuple`
API.)
``NamedTuple`` subclasses can also have docstrings and methods::
class Employee(NamedTuple):
"""Represents an employee."""
name: str
id: int = 3
def __repr__(self) -> str:
return f'<Employee {self.name}, id={self.id}>'
``NamedTuple`` subclasses can be generic::
class Group(NamedTuple, Generic[T]):
key: T
group: list[T]
Backward-compatible usage::
Employee = NamedTuple('Employee', [('name', str), ('id', int)])
.. versionchanged:: 3.6
Added support for :pep:`526` variable annotation syntax.
.. versionchanged:: 3.6.1
Added support for default values, methods, and docstrings.
.. versionchanged:: 3.8
The ``_field_types`` and ``__annotations__`` attributes are
now regular dictionaries instead of instances of ``OrderedDict``.
.. versionchanged:: 3.9
Removed the ``_field_types`` attribute in favor of the more
standard ``__annotations__`` attribute which has the same information.
.. versionchanged:: 3.11
Added support for generic namedtuples.
.. class:: NewType(name, tp)
A helper class to indicate a distinct type to a typechecker,
see :ref:`distinct`. At runtime it returns an object that returns
its argument when called.
Usage::
UserId = NewType('UserId', int)
first_user = UserId(1)
.. versionadded:: 3.5.2
.. versionchanged:: 3.10
``NewType`` is now a class rather than a function.
.. class:: Protocol(Generic)
@ -1659,94 +1747,6 @@ These are not used in annotations. They are building blocks for creating generic
for more details.
Other special directives
""""""""""""""""""""""""
These are not used in annotations. They are building blocks for declaring types.
.. class:: NamedTuple
Typed version of :func:`collections.namedtuple`.
Usage::
class Employee(NamedTuple):
name: str
id: int
This is equivalent to::
Employee = collections.namedtuple('Employee', ['name', 'id'])
To give a field a default value, you can assign to it in the class body::
class Employee(NamedTuple):
name: str
id: int = 3
employee = Employee('Guido')
assert employee.id == 3
Fields with a default value must come after any fields without a default.
The resulting class has an extra attribute ``__annotations__`` giving a
dict that maps the field names to the field types. (The field names are in
the ``_fields`` attribute and the default values are in the
``_field_defaults`` attribute, both of which are part of the :func:`~collections.namedtuple`
API.)
``NamedTuple`` subclasses can also have docstrings and methods::
class Employee(NamedTuple):
"""Represents an employee."""
name: str
id: int = 3
def __repr__(self) -> str:
return f'<Employee {self.name}, id={self.id}>'
``NamedTuple`` subclasses can be generic::
class Group(NamedTuple, Generic[T]):
key: T
group: list[T]
Backward-compatible usage::
Employee = NamedTuple('Employee', [('name', str), ('id', int)])
.. versionchanged:: 3.6
Added support for :pep:`526` variable annotation syntax.
.. versionchanged:: 3.6.1
Added support for default values, methods, and docstrings.
.. versionchanged:: 3.8
The ``_field_types`` and ``__annotations__`` attributes are
now regular dictionaries instead of instances of ``OrderedDict``.
.. versionchanged:: 3.9
Removed the ``_field_types`` attribute in favor of the more
standard ``__annotations__`` attribute which has the same information.
.. versionchanged:: 3.11
Added support for generic namedtuples.
.. class:: NewType(name, tp)
A helper class to indicate a distinct type to a typechecker,
see :ref:`distinct`. At runtime it returns an object that returns
its argument when called.
Usage::
UserId = NewType('UserId', int)
first_user = UserId(1)
.. versionadded:: 3.5.2
.. versionchanged:: 3.10
``NewType`` is now a class rather than a function.
.. class:: TypedDict(dict)
Special construct to add type hints to a dictionary.