diff options
author | Jelle Zijlstra <jelle.zijlstra@gmail.com> | 2023-05-21 13:31:26 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-21 13:31:26 (GMT) |
commit | abb32de8c4e9541fbd0c6b14dc937193078e6955 (patch) | |
tree | b0cbf1cc90b801c508da1ff6d4bfb078fc01c7a9 /Doc | |
parent | dc0c41b2e5ec64854caa9055f2c7388e22fa4bf8 (diff) | |
download | cpython-abb32de8c4e9541fbd0c6b14dc937193078e6955.zip cpython-abb32de8c4e9541fbd0c6b14dc937193078e6955.tar.gz cpython-abb32de8c4e9541fbd0c6b14dc937193078e6955.tar.bz2 |
[3.11] typing docs: Move some classes out of the "Generics" section (GH-104707) (#104721)
- 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.
(cherry picked from commit ab71acd67b5b09926498b8c7f855bdb28ac0ec2f)
---------
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
Diffstat (limited to 'Doc')
-rw-r--r-- | Doc/library/typing.rst | 247 |
1 files changed, 125 insertions, 122 deletions
diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 4430454..33cf1cb 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -611,6 +611,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 @@ -912,13 +927,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]) @@ -1203,6 +1218,34 @@ 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 + + .. versionadded:: 3.11 + Building generic types """""""""""""""""""""" @@ -1404,32 +1447,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 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 - - .. versionadded:: 3.11 - .. class:: ParamSpec(name, *, bound=None, covariant=False, contravariant=False) Parameter specification variable. A specialized version of @@ -1528,97 +1545,6 @@ These are not used in annotations. They are building blocks for creating generic .. versionadded:: 3.10 -.. 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 - -.. class:: Protocol(Generic) - - Base class for protocol classes. Protocol classes are defined like this:: - - class Proto(Protocol): - def meth(self) -> int: - ... - - Such classes are primarily used with static type checkers that recognize - structural subtyping (static duck-typing), for example:: - - class C: - def meth(self) -> int: - return 0 - - def func(x: Proto) -> int: - return x.meth() - - func(C()) # Passes static type check - - See :pep:`544` for more details. Protocol classes decorated with - :func:`runtime_checkable` (described later) act as simple-minded runtime - protocols that check only the presence of given attributes, ignoring their - type signatures. - - Protocol classes can be generic, for example:: - - class GenProto(Protocol[T]): - def meth(self) -> T: - ... - - .. versionadded:: 3.8 - -.. decorator:: runtime_checkable - - Mark a protocol class as a runtime protocol. - - Such a protocol can be used with :func:`isinstance` and :func:`issubclass`. - This raises :exc:`TypeError` when applied to a non-protocol class. This - allows a simple-minded structural check, very similar to "one trick ponies" - in :mod:`collections.abc` such as :class:`~collections.abc.Iterable`. For example:: - - @runtime_checkable - class Closable(Protocol): - def close(self): ... - - assert isinstance(open('/some/file'), Closable) - - @runtime_checkable - class Named(Protocol): - name: str - - import threading - assert isinstance(threading.Thread(name='Bob'), Named) - - .. note:: - - :func:`!runtime_checkable` will check only the presence of the required - methods or attributes, not their type signatures or types. - For example, :class:`ssl.SSLObject` - is a class, therefore it passes an :func:`issubclass` - check against :data:`Callable`. However, the - ``ssl.SSLObject.__init__`` method exists only to raise a - :exc:`TypeError` with a more informative message, therefore making - it impossible to call (instantiate) :class:`ssl.SSLObject`. - - .. note:: - - An :func:`isinstance` check against a runtime-checkable protocol can be - surprisingly slow compared to an ``isinstance()`` check against - a non-protocol class. Consider using alternative idioms such as - :func:`hasattr` calls for structural checks in performance-sensitive - code. - - .. versionadded:: 3.8 - Other special directives """""""""""""""""""""""" @@ -1707,6 +1633,83 @@ These are not used in annotations. They are building blocks for declaring types. .. versionchanged:: 3.10 ``NewType`` is now a class rather than a function. +.. class:: Protocol(Generic) + + Base class for protocol classes. Protocol classes are defined like this:: + + class Proto(Protocol): + def meth(self) -> int: + ... + + Such classes are primarily used with static type checkers that recognize + structural subtyping (static duck-typing), for example:: + + class C: + def meth(self) -> int: + return 0 + + def func(x: Proto) -> int: + return x.meth() + + func(C()) # Passes static type check + + See :pep:`544` for more details. Protocol classes decorated with + :func:`runtime_checkable` (described later) act as simple-minded runtime + protocols that check only the presence of given attributes, ignoring their + type signatures. + + Protocol classes can be generic, for example:: + + class GenProto(Protocol[T]): + def meth(self) -> T: + ... + + .. versionadded:: 3.8 + +.. decorator:: runtime_checkable + + Mark a protocol class as a runtime protocol. + + Such a protocol can be used with :func:`isinstance` and :func:`issubclass`. + This raises :exc:`TypeError` when applied to a non-protocol class. This + allows a simple-minded structural check, very similar to "one trick ponies" + in :mod:`collections.abc` such as :class:`~collections.abc.Iterable`. For example:: + + @runtime_checkable + class Closable(Protocol): + def close(self): ... + + assert isinstance(open('/some/file'), Closable) + + @runtime_checkable + class Named(Protocol): + name: str + + import threading + assert isinstance(threading.Thread(name='Bob'), Named) + + .. note:: + + :func:`!runtime_checkable` will check only the presence of the required + methods or attributes, not their type signatures or types. + For example, :class:`ssl.SSLObject` + is a class, therefore it passes an :func:`issubclass` + check against :data:`Callable`. However, the + ``ssl.SSLObject.__init__`` method exists only to raise a + :exc:`TypeError` with a more informative message, therefore making + it impossible to call (instantiate) :class:`ssl.SSLObject`. + + .. note:: + + An :func:`isinstance` check against a runtime-checkable protocol can be + surprisingly slow compared to an ``isinstance()`` check against + a non-protocol class. Consider using alternative idioms such as + :func:`hasattr` calls for structural checks in performance-sensitive + code. + + .. versionadded:: 3.8 + + .. class:: TypedDict(dict) Special construct to add type hints to a dictionary. |