[3.12] Miscellaneous improvements to the typing docs (GH-105529) (#105567)

Miscellaneous improvements to the typing docs (GH-105529)

Mostly, these are changes so that we use shorter sentences and shorter paragraphs. In particular, I've tried to make the first sentence introducing each object in the typing API short and declarative.
(cherry picked from commit 8e755923c9)

Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
This commit is contained in:
Miss Islington (bot) 2023-06-09 08:37:33 -07:00 committed by GitHub
parent d29e86bea3
commit 7c298d2dc5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 229 additions and 145 deletions

View file

@ -158,9 +158,6 @@ Type aliases are useful for simplifying complex type signatures. For example::
servers: Sequence[tuple[tuple[str, int], dict[str, str]]]) -> None: servers: Sequence[tuple[tuple[str, int], dict[str, str]]]) -> None:
... ...
Note that ``None`` as a type hint is a special case and is replaced by
``type(None)``.
The :keyword:`type` statement is new in Python 3.12. For backwards The :keyword:`type` statement is new in Python 3.12. For backwards
compatibility, type aliases can also be created through simple assignment:: compatibility, type aliases can also be created through simple assignment::
@ -699,24 +696,31 @@ These can be used as types in annotations and do not support ``[]``.
.. data:: AnyStr .. data:: AnyStr
``AnyStr`` is a :ref:`constrained type variable <typing-constrained-typevar>` defined as A :ref:`constrained type variable <typing-constrained-typevar>`.
``AnyStr = TypeVar('AnyStr', str, bytes)``.
It is meant to be used for functions that may accept any kind of string Definition::
without allowing different kinds of strings to mix. For example::
AnyStr = TypeVar('AnyStr', str, bytes)
``AnyStr`` is meant to be used for functions that may accept :class:`str` or
:class:`bytes` arguments but cannot allow the two to mix.
For example::
def concat(a: AnyStr, b: AnyStr) -> AnyStr: def concat(a: AnyStr, b: AnyStr) -> AnyStr:
return a + b return a + b
concat(u"foo", u"bar") # Ok, output has type 'unicode' concat("foo", "bar") # OK, output has type 'str'
concat(b"foo", b"bar") # Ok, output has type 'bytes' concat(b"foo", b"bar") # OK, output has type 'bytes'
concat(u"foo", b"bar") # Error, cannot mix unicode and bytes concat("foo", b"bar") # Error, cannot mix str and bytes
.. data:: LiteralString .. data:: LiteralString
Special type that includes only literal strings. A string Special type that includes only literal strings.
Any string
literal is compatible with ``LiteralString``, as is another literal is compatible with ``LiteralString``, as is another
``LiteralString``, but an object typed as just ``str`` is not. ``LiteralString``. However, an object typed as just ``str`` is not.
A string created by composing ``LiteralString``-typed objects A string created by composing ``LiteralString``-typed objects
is also acceptable as a ``LiteralString``. is also acceptable as a ``LiteralString``.
@ -728,15 +732,15 @@ These can be used as types in annotations and do not support ``[]``.
... ...
def caller(arbitrary_string: str, literal_string: LiteralString) -> None: def caller(arbitrary_string: str, literal_string: LiteralString) -> None:
run_query("SELECT * FROM students") # ok run_query("SELECT * FROM students") # OK
run_query(literal_string) # ok run_query(literal_string) # OK
run_query("SELECT * FROM " + literal_string) # ok run_query("SELECT * FROM " + literal_string) # OK
run_query(arbitrary_string) # type checker error run_query(arbitrary_string) # type checker error
run_query( # type checker error run_query( # type checker error
f"SELECT * FROM students WHERE name = {arbitrary_string}" f"SELECT * FROM students WHERE name = {arbitrary_string}"
) )
This is useful for sensitive APIs where arbitrary user-generated ``LiteralString`` is useful for sensitive APIs where arbitrary user-generated
strings could generate problems. For example, the two cases above strings could generate problems. For example, the two cases above
that generate type checker errors could be vulnerable to an SQL that generate type checker errors could be vulnerable to an SQL
injection attack. injection attack.
@ -766,7 +770,7 @@ These can be used as types in annotations and do not support ``[]``.
case str(): case str():
print("It's a str") print("It's a str")
case _: case _:
never_call_me(arg) # ok, arg is of type Never never_call_me(arg) # OK, arg is of type Never
.. versionadded:: 3.11 .. versionadded:: 3.11
@ -776,6 +780,7 @@ These can be used as types in annotations and do not support ``[]``.
.. data:: NoReturn .. data:: NoReturn
Special type indicating that a function never returns. Special type indicating that a function never returns.
For example:: For example::
from typing import NoReturn from typing import NoReturn
@ -795,6 +800,7 @@ These can be used as types in annotations and do not support ``[]``.
.. data:: Self .. data:: Self
Special type to represent the current enclosed class. Special type to represent the current enclosed class.
For example:: For example::
from typing import Self from typing import Self
@ -943,8 +949,6 @@ These can be used as types in annotations using ``[]``, each having a unique syn
.. data:: Optional .. data:: Optional
Optional type.
``Optional[X]`` is equivalent to ``X | None`` (or ``Union[X, None]``). ``Optional[X]`` is equivalent to ``X | None`` (or ``Union[X, None]``).
Note that this is not the same concept as an optional argument, Note that this is not the same concept as an optional argument,
@ -1008,8 +1012,11 @@ These can be used as types in annotations using ``[]``, each having a unique syn
.. data:: Concatenate .. data:: Concatenate
Used with :data:`Callable` and :class:`ParamSpec` to type annotate a higher Special form for annotating higher-order functions.
order callable which adds, removes, or transforms parameters of another
``Concatenate`` can be used in conjunction with :data:`Callable` and
:class:`ParamSpec` to annotate a higher-order callable which adds, removes,
or transforms parameters of another
callable. Usage is in the form callable. Usage is in the form
``Concatenate[Arg1Type, Arg2Type, ..., ParamSpecVariable]``. ``Concatenate`` ``Concatenate[Arg1Type, Arg2Type, ..., ParamSpecVariable]``. ``Concatenate``
is currently only valid when used as the first argument to a :data:`Callable`. is currently only valid when used as the first argument to a :data:`Callable`.
@ -1110,18 +1117,22 @@ These can be used as types in annotations using ``[]``, each having a unique syn
.. data:: Literal .. data:: Literal
A type that can be used to indicate to type checkers that the Special typing form to define "literal types".
corresponding variable or function parameter has a value equivalent to
the provided literal (or one of several literals). For example:: ``Literal`` can be used to indicate to type checkers that the
annotated object has a value equivalent to one of the
provided literals.
For example::
def validate_simple(data: Any) -> Literal[True]: # always returns True def validate_simple(data: Any) -> Literal[True]: # always returns True
... ...
MODE = Literal['r', 'rb', 'w', 'wb'] type Mode = Literal['r', 'rb', 'w', 'wb']
def open_helper(file: str, mode: MODE) -> str: def open_helper(file: str, mode: Mode) -> str:
... ...
open_helper('/some/path', 'r') # Passes type check open_helper('/some/path', 'r') # Passes type check
open_helper('/other/path', 'typo') # Error in type checker open_helper('/other/path', 'typo') # Error in type checker
``Literal[...]`` cannot be subclassed. At runtime, an arbitrary value ``Literal[...]`` cannot be subclassed. At runtime, an arbitrary value
@ -1164,8 +1175,12 @@ These can be used as types in annotations using ``[]``, each having a unique syn
.. data:: Final .. data:: Final
A special typing construct to indicate to type checkers that a name Special typing construct to indicate final names to type checkers.
cannot be re-assigned or overridden in a subclass. For example::
Final names cannot be reassigned in any scope. Final names declared in class
scopes cannot be overridden in subclasses.
For example::
MAX_SIZE: Final = 9000 MAX_SIZE: Final = 9000
MAX_SIZE += 1 # Error reported by type checker MAX_SIZE += 1 # Error reported by type checker
@ -1183,10 +1198,17 @@ These can be used as types in annotations using ``[]``, each having a unique syn
.. data:: Required .. data:: Required
Special typing construct to mark a :class:`TypedDict` key as required.
This is mainly useful for ``total=False`` TypedDicts. See :class:`TypedDict`
and :pep:`655` for more details.
.. versionadded:: 3.11
.. data:: NotRequired .. data:: NotRequired
Special typing constructs that mark individual keys of a :class:`TypedDict` Special typing construct to mark a :class:`TypedDict` key as potentially
as either required or non-required respectively. missing.
See :class:`TypedDict` and :pep:`655` for more details. See :class:`TypedDict` and :pep:`655` for more details.
@ -1335,7 +1357,9 @@ These can be used as types in annotations using ``[]``, each having a unique syn
.. data:: TypeGuard .. data:: TypeGuard
Special typing form used to annotate the return type of a user-defined Special typing construct for marking user-defined type guard functions.
``TypeGuard`` can be used to annotate the return type of a user-defined
type guard function. ``TypeGuard`` only accepts a single type argument. type guard function. ``TypeGuard`` only accepts a single type argument.
At runtime, functions marked this way should return a boolean. At runtime, functions marked this way should return a boolean.
@ -1402,8 +1426,9 @@ These can be used as types in annotations using ``[]``, each having a unique syn
.. data:: Unpack .. data:: Unpack
A typing operator that conceptually marks an object as having been Typing operator to conceptually mark an object as having been unpacked.
unpacked. For example, using the unpack operator ``*`` on a
For example, using the unpack operator ``*`` on a
:class:`type variable tuple <TypeVarTuple>` is equivalent to using ``Unpack`` :class:`type variable tuple <TypeVarTuple>` is equivalent to using ``Unpack``
to mark the type variable tuple as having been unpacked:: to mark the type variable tuple as having been unpacked::
@ -1855,11 +1880,16 @@ without the dedicated syntax, as documented below.
for runtime introspection and have no special meaning to static type checkers. for runtime introspection and have no special meaning to static type checkers.
Calling :func:`get_origin` on either of these objects will return the Calling :func:`get_origin` on either of these objects will return the
original ``ParamSpec``:: original ``ParamSpec``:
P = ParamSpec("P") .. doctest::
get_origin(P.args) # returns P
get_origin(P.kwargs) # returns P >>> from typing import ParamSpec
>>> P = ParamSpec("P")
>>> get_origin(P.args) is P
True
>>> get_origin(P.kwargs) is P
True
.. versionadded:: 3.10 .. versionadded:: 3.10
@ -2010,13 +2040,15 @@ These are not used in annotations. They are building blocks for declaring types.
.. class:: NewType(name, tp) .. class:: NewType(name, tp)
A helper class to indicate a distinct type to a typechecker, Helper class to create low-overhead :ref:`distinct types <distinct>`.
see :ref:`distinct`. At runtime it returns an object that returns
its argument when called. A ``NewType`` is considered a distinct type by a typechecker. At runtime,
however, calling a ``NewType`` returns its argument unchanged.
Usage:: Usage::
UserId = NewType('UserId', int) UserId = NewType('UserId', int) # Declare the NewType "UserId"
first_user = UserId(1) first_user = UserId(1) # "UserId" returns the argument unchanged at runtime
.. attribute:: __module__ .. attribute:: __module__
@ -2037,7 +2069,9 @@ These are not used in annotations. They are building blocks for declaring types.
.. class:: Protocol(Generic) .. class:: Protocol(Generic)
Base class for protocol classes. Protocol classes are defined like this:: Base class for protocol classes.
Protocol classes are defined like this::
class Proto(Protocol): class Proto(Protocol):
def meth(self) -> int: def meth(self) -> int:
@ -2490,11 +2524,12 @@ Other concrete types
.. class:: Pattern .. class:: Pattern
Match Match
These type aliases Deprecated aliases corresponding to the return types from
correspond to the return types from :func:`re.compile` and :func:`re.compile` and :func:`re.match`.
:func:`re.match`. These types (and the corresponding functions)
are generic in ``AnyStr`` and can be made specific by writing These types (and the corresponding functions) are generic over
``Pattern[str]``, ``Pattern[bytes]``, ``Match[str]``, or :data:`AnyStr`. ``Pattern`` can be specialised as ``Pattern[str]`` or
``Pattern[bytes]``; ``Match`` can be specialised as ``Match[str]`` or
``Match[bytes]``. ``Match[bytes]``.
.. deprecated-removed:: 3.8 3.13 .. deprecated-removed:: 3.8 3.13
@ -2507,7 +2542,9 @@ Other concrete types
.. class:: Text .. class:: Text
``Text`` is an alias for ``str``. It is provided to supply a forward Deprecated alias for :class:`str`.
``Text`` is provided to supply a forward
compatible path for Python 2 code: in Python 2, ``Text`` is an alias for compatible path for Python 2 code: in Python 2, ``Text`` is an alias for
``unicode``. ``unicode``.
@ -2584,6 +2621,7 @@ Corresponding to collections in :mod:`collections.abc`
.. class:: Mapping(Collection[KT], Generic[KT, VT_co]) .. class:: Mapping(Collection[KT], Generic[KT, VT_co])
Deprecated alias to :class:`collections.abc.Mapping`. Deprecated alias to :class:`collections.abc.Mapping`.
This type can be used as follows:: This type can be used as follows::
def get_position_in_index(word_list: Mapping[str, int], word: str) -> int: def get_position_in_index(word_list: Mapping[str, int], word: str) -> int:
@ -2935,6 +2973,7 @@ Functions and decorators
last case can never execute, because ``arg`` is either last case can never execute, because ``arg`` is either
an :class:`int` or a :class:`str`, and both options are covered by an :class:`int` or a :class:`str`, and both options are covered by
earlier cases. earlier cases.
If a type checker finds that a call to ``assert_never()`` is If a type checker finds that a call to ``assert_never()`` is
reachable, it will emit an error. For example, if the type annotation reachable, it will emit an error. For example, if the type annotation
for ``arg`` was instead ``int | str | float``, the type checker would for ``arg`` was instead ``int | str | float``, the type checker would
@ -2985,11 +3024,14 @@ Functions and decorators
.. decorator:: dataclass_transform .. decorator:: dataclass_transform
:data:`~typing.dataclass_transform` may be used to Decorator to mark an object as providing
:func:`~dataclasses.dataclass`-like behavior.
``dataclass_transform`` may be used to
decorate a class, metaclass, or a function that is itself a decorator. decorate a class, metaclass, or a function that is itself a decorator.
The presence of ``@dataclass_transform()`` tells a static type checker that the The presence of ``@dataclass_transform()`` tells a static type checker that the
decorated object performs runtime "magic" that decorated object performs runtime "magic" that
transforms a class, giving it :func:`dataclasses.dataclass`-like behaviors. transforms a class in a similar way to :func:`dataclasses.dataclass`.
Example usage with a decorator function: Example usage with a decorator function:
@ -3090,16 +3132,22 @@ Functions and decorators
.. decorator:: overload .. decorator:: overload
Decorator for creating overloaded functions and methods.
The ``@overload`` decorator allows describing functions and methods The ``@overload`` decorator allows describing functions and methods
that support multiple different combinations of argument types. A series that support multiple different combinations of argument types. A series
of ``@overload``-decorated definitions must be followed by exactly one of ``@overload``-decorated definitions must be followed by exactly one
non-``@overload``-decorated definition (for the same function/method). non-``@overload``-decorated definition (for the same function/method).
The ``@overload``-decorated definitions are for the benefit of the
``@overload``-decorated definitions are for the benefit of the
type checker only, since they will be overwritten by the type checker only, since they will be overwritten by the
non-``@overload``-decorated definition, while the latter is used at non-``@overload``-decorated definition. The non-``@overload``-decorated
definition, meanwhile, will be used at
runtime but should be ignored by a type checker. At runtime, calling runtime but should be ignored by a type checker. At runtime, calling
a ``@overload``-decorated function directly will raise an ``@overload``-decorated function directly will raise
:exc:`NotImplementedError`. An example of overload that gives a more :exc:`NotImplementedError`.
An example of overload that gives a more
precise type than can be expressed using a union or a type variable: precise type than can be expressed using a union or a type variable:
.. testcode:: .. testcode::
@ -3126,7 +3174,9 @@ Functions and decorators
.. function:: get_overloads(func) .. function:: get_overloads(func)
Return a sequence of :func:`@overload <overload>`-decorated definitions for Return a sequence of :func:`@overload <overload>`-decorated definitions for
*func*. *func* is the function object for the implementation of the *func*.
*func* is the function object for the implementation of the
overloaded function. For example, given the definition of ``process`` in overloaded function. For example, given the definition of ``process`` in
the documentation for :func:`@overload <overload>`, the documentation for :func:`@overload <overload>`,
``get_overloads(process)`` will return a sequence of three function objects ``get_overloads(process)`` will return a sequence of three function objects
@ -3141,16 +3191,21 @@ Functions and decorators
.. function:: clear_overloads() .. function:: clear_overloads()
Clear all registered overloads in the internal registry. This can be used Clear all registered overloads in the internal registry.
to reclaim the memory used by the registry.
This can be used to reclaim the memory used by the registry.
.. versionadded:: 3.11 .. versionadded:: 3.11
.. decorator:: final .. decorator:: final
A decorator to indicate to type checkers that the decorated method Decorator to indicate final methods and final classes.
cannot be overridden, and the decorated class cannot be subclassed.
Decorating a method with ``@final`` indicates to a type checker that the
method cannot be overridden in a subclass. Decorating a class with ``@final``
indicates that it cannot be subclassed.
For example:: For example::
class Base: class Base:
@ -3173,7 +3228,7 @@ Functions and decorators
.. versionadded:: 3.8 .. versionadded:: 3.8
.. versionchanged:: 3.11 .. versionchanged:: 3.11
The decorator will now set the ``__final__`` attribute to ``True`` The decorator will now attempt to set a ``__final__`` attribute to ``True``
on the decorated object. Thus, a check like on the decorated object. Thus, a check like
``if getattr(obj, "__final__", False)`` can be used at runtime ``if getattr(obj, "__final__", False)`` can be used at runtime
to determine whether an object ``obj`` has been marked as final. to determine whether an object ``obj`` has been marked as final.
@ -3185,11 +3240,13 @@ Functions and decorators
Decorator to indicate that annotations are not type hints. Decorator to indicate that annotations are not type hints.
This works as class or function :term:`decorator`. With a class, it This works as a class or function :term:`decorator`. With a class, it
applies recursively to all methods and classes defined in that class applies recursively to all methods and classes defined in that class
(but not to methods defined in its superclasses or subclasses). (but not to methods defined in its superclasses or subclasses). Type
checkers will ignore all annotations in a function or class with this
decorator.
This mutates the function(s) in place. ``@no_type_check`` mutates the decorated object in place.
.. decorator:: no_type_check_decorator .. decorator:: no_type_check_decorator
@ -3201,8 +3258,11 @@ Functions and decorators
.. decorator:: override .. decorator:: override
A decorator for methods that indicates to type checkers that this method Decorator to indicate that a method in a subclass is intended to override a
should override a method or attribute with the same name on a base class. method or attribute in a superclass.
Type checkers should emit an error if a method decorated with ``@override``
does not, in fact, override anything.
This helps prevent bugs that may occur when a base class is changed without This helps prevent bugs that may occur when a base class is changed without
an equivalent change to a child class. an equivalent change to a child class.
@ -3225,7 +3285,7 @@ Functions and decorators
There is no runtime checking of this property. There is no runtime checking of this property.
The decorator will set the ``__override__`` attribute to ``True`` on The decorator will attempt to set an ``__override__`` attribute to ``True`` on
the decorated object. Thus, a check like the decorated object. Thus, a check like
``if getattr(obj, "__override__", False)`` can be used at runtime to determine ``if getattr(obj, "__override__", False)`` can be used at runtime to determine
whether an object ``obj`` has been marked as an override. If the decorated object whether an object ``obj`` has been marked as an override. If the decorated object
@ -3239,7 +3299,7 @@ Functions and decorators
.. decorator:: type_check_only .. decorator:: type_check_only
Decorator to mark a class or function to be unavailable at runtime. Decorator to mark a class or function as unavailable at runtime.
This decorator is itself not available at runtime. It is mainly This decorator is itself not available at runtime. It is mainly
intended to mark classes that are defined in type stub files if intended to mark classes that are defined in type stub files if
@ -3293,6 +3353,7 @@ Introspection helpers
.. versionchanged:: 3.9 .. versionchanged:: 3.9
Added ``include_extras`` parameter as part of :pep:`593`. Added ``include_extras`` parameter as part of :pep:`593`.
See the documentation on :data:`Annotated` for more information.
.. versionchanged:: 3.11 .. versionchanged:: 3.11
Previously, ``Optional[t]`` was added for function and method annotations Previously, ``Optional[t]`` was added for function and method annotations
@ -3302,11 +3363,14 @@ Introspection helpers
.. function:: get_origin(tp) .. function:: get_origin(tp)
Get the unsubscripted version of a type: for a typing object of the form Get the unsubscripted version of a type: for a typing object of the form
``X[Y, Z, ...]`` return ``X``. If ``X`` is a generic alias for a builtin or ``X[Y, Z, ...]`` return ``X``.
:mod:`collections` class, it gets normalized to the original class.
If ``X`` is a typing-module alias for a builtin or
:mod:`collections` class, it will be normalized to the original class.
If ``X`` is an instance of :class:`ParamSpecArgs` or :class:`ParamSpecKwargs`, If ``X`` is an instance of :class:`ParamSpecArgs` or :class:`ParamSpecKwargs`,
return the underlying :class:`ParamSpec`. return the underlying :class:`ParamSpec`.
Return ``None`` for unsupported objects. Return ``None`` for unsupported objects.
Examples: Examples:
.. testcode:: .. testcode::
@ -3324,10 +3388,12 @@ Introspection helpers
Get type arguments with all substitutions performed: for a typing object Get type arguments with all substitutions performed: for a typing object
of the form ``X[Y, Z, ...]`` return ``(Y, Z, ...)``. of the form ``X[Y, Z, ...]`` return ``(Y, Z, ...)``.
If ``X`` is a union or :class:`Literal` contained in another If ``X`` is a union or :class:`Literal` contained in another
generic type, the order of ``(Y, Z, ...)`` may be different from the order generic type, the order of ``(Y, Z, ...)`` may be different from the order
of the original arguments ``[Y, Z, ...]`` due to type caching. of the original arguments ``[Y, Z, ...]`` due to type caching.
Return ``()`` for unsupported objects. Return ``()`` for unsupported objects.
Examples: Examples:
.. testcode:: .. testcode::
@ -3361,9 +3427,10 @@ Introspection helpers
.. class:: ForwardRef .. class:: ForwardRef
A class used for internal typing representation of string forward references. Class used for internal typing representation of string forward references.
For example, ``List["SomeClass"]`` is implicitly transformed into For example, ``List["SomeClass"]`` is implicitly transformed into
``List[ForwardRef("SomeClass")]``. This class should not be instantiated by ``List[ForwardRef("SomeClass")]``. ``ForwardRef`` should not be instantiated by
a user, but may be used by introspection tools. a user, but may be used by introspection tools.
.. note:: .. note::
@ -3379,7 +3446,9 @@ Constant
.. data:: TYPE_CHECKING .. data:: TYPE_CHECKING
A special constant that is assumed to be ``True`` by 3rd party static A special constant that is assumed to be ``True`` by 3rd party static
type checkers. It is ``False`` at runtime. Usage:: type checkers. It is ``False`` at runtime.
Usage::
if TYPE_CHECKING: if TYPE_CHECKING:
import expensive_mod import expensive_mod

View file

@ -567,7 +567,7 @@ def Never(self, parameters):
case str(): case str():
print("It's a str") print("It's a str")
case _: case _:
never_call_me(arg) # ok, arg is of type Never never_call_me(arg) # OK, arg is of type Never
""" """
raise TypeError(f"{self} is not subscriptable") raise TypeError(f"{self} is not subscriptable")
@ -600,13 +600,13 @@ def LiteralString(self, parameters):
from typing import LiteralString from typing import LiteralString
def run_query(sql: LiteralString) -> ... def run_query(sql: LiteralString) -> None:
... ...
def caller(arbitrary_string: str, literal_string: LiteralString) -> None: def caller(arbitrary_string: str, literal_string: LiteralString) -> None:
run_query("SELECT * FROM students") # ok run_query("SELECT * FROM students") # OK
run_query(literal_string) # ok run_query(literal_string) # OK
run_query("SELECT * FROM " + literal_string) # ok run_query("SELECT * FROM " + literal_string) # OK
run_query(arbitrary_string) # type checker error run_query(arbitrary_string) # type checker error
run_query( # type checker error run_query( # type checker error
f"SELECT * FROM students WHERE name = {arbitrary_string}" f"SELECT * FROM students WHERE name = {arbitrary_string}"
@ -2124,7 +2124,7 @@ def assert_type(val, typ, /):
emits an error if the value is not of the specified type:: emits an error if the value is not of the specified type::
def greet(name: str) -> None: def greet(name: str) -> None:
assert_type(name, str) # ok assert_type(name, str) # OK
assert_type(name, int) # type checker error assert_type(name, int) # type checker error
""" """
return val return val

View file

@ -443,23 +443,25 @@ static PyMethodDef typevar_methods[] = {
PyDoc_STRVAR(typevar_doc, PyDoc_STRVAR(typevar_doc,
"Type variable.\n\ "Type variable.\n\
\n\ \n\
The preferred way to construct a type variable is via the dedicated syntax\n\ The preferred way to construct a type variable is via the dedicated\n\
for generic functions, classes, and type aliases:\n\ syntax for generic functions, classes, and type aliases::\n\
\n\ \n\
class Sequence[T]: # T is a TypeVar\n\ class Sequence[T]: # T is a TypeVar\n\
...\n\ ...\n\
\n\ \n\
This syntax can also be used to create bound and constrained type\n\ This syntax can also be used to create bound and constrained type\n\
variables:\n\ variables::\n\
\n\ \n\
class StrSequence[S: str]: # S is a TypeVar bound to str\n\ # S is a TypeVar bound to str\n\
class StrSequence[S: str]:\n\
...\n\ ...\n\
\n\ \n\
class StrOrBytesSequence[A: (str, bytes)]: # A is a TypeVar constrained to str or bytes\n\ # A is a TypeVar constrained to str or bytes\n\
class StrOrBytesSequence[A: (str, bytes)]:\n\
...\n\ ...\n\
\n\ \n\
However, if desired, reusable type variables can also be constructed\n\ However, if desired, reusable type variables can also be constructed\n\
manually, like so:\n\ manually, like so::\n\
\n\ \n\
T = TypeVar('T') # Can be anything\n\ T = TypeVar('T') # Can be anything\n\
S = TypeVar('S', bound=str) # Can be any subtype of str\n\ S = TypeVar('S', bound=str) # Can be any subtype of str\n\
@ -469,12 +471,13 @@ Type variables exist primarily for the benefit of static type\n\
checkers. They serve as the parameters for generic types as well\n\ checkers. They serve as the parameters for generic types as well\n\
as for generic function and type alias definitions.\n\ as for generic function and type alias definitions.\n\
\n\ \n\
The variance of type variables is inferred by type checkers when they are created\n\ The variance of type variables is inferred by type checkers when they\n\
through the type parameter syntax and when ``infer_variance=True`` is passed.\n\ are created through the type parameter syntax and when\n\
Manually created type variables may be explicitly marked covariant or\n\ ``infer_variance=True`` is passed. Manually created type variables may\n\
contravariant by passing ``covariant=True`` or ``contravariant=True``.\n\ be explicitly marked covariant or contravariant by passing\n\
By default, manually created type variables are invariant. See PEP 484\n\ ``covariant=True`` or ``contravariant=True``. By default, manually\n\
and PEP 695 for more details.\n\ created type variables are invariant. See PEP 484 and PEP 695 for more\n\
details.\n\
"); ");
static PyType_Slot typevar_slots[] = { static PyType_Slot typevar_slots[] = {
@ -616,12 +619,14 @@ PyDoc_STRVAR(paramspecargs_doc,
\n\ \n\
Given a ParamSpec object P, P.args is an instance of ParamSpecArgs.\n\ Given a ParamSpec object P, P.args is an instance of ParamSpecArgs.\n\
\n\ \n\
ParamSpecArgs objects have a reference back to their ParamSpec:\n\ ParamSpecArgs objects have a reference back to their ParamSpec::\n\
\n\ \n\
P.args.__origin__ is P\n\ >>> P = ParamSpec(\"P\")\n\
>>> P.args.__origin__ is P\n\
True\n\
\n\ \n\
This type is meant for runtime introspection and has no special meaning to\n\ This type is meant for runtime introspection and has no special meaning\n\
static type checkers.\n\ to static type checkers.\n\
"); ");
static PyType_Slot paramspecargs_slots[] = { static PyType_Slot paramspecargs_slots[] = {
@ -693,12 +698,14 @@ PyDoc_STRVAR(paramspeckwargs_doc,
\n\ \n\
Given a ParamSpec object P, P.kwargs is an instance of ParamSpecKwargs.\n\ Given a ParamSpec object P, P.kwargs is an instance of ParamSpecKwargs.\n\
\n\ \n\
ParamSpecKwargs objects have a reference back to their ParamSpec:\n\ ParamSpecKwargs objects have a reference back to their ParamSpec::\n\
\n\ \n\
P.kwargs.__origin__ is P\n\ >>> P = ParamSpec(\"P\")\n\
>>> P.kwargs.__origin__ is P\n\
True\n\
\n\ \n\
This type is meant for runtime introspection and has no special meaning to\n\ This type is meant for runtime introspection and has no special meaning\n\
static type checkers.\n\ to static type checkers.\n\
"); ");
static PyType_Slot paramspeckwargs_slots[] = { static PyType_Slot paramspeckwargs_slots[] = {
@ -935,24 +942,26 @@ static PyMethodDef paramspec_methods[] = {
PyDoc_STRVAR(paramspec_doc, PyDoc_STRVAR(paramspec_doc,
"Parameter specification variable.\n\ "Parameter specification variable.\n\
\n\ \n\
The preferred way to construct a parameter specification is via the dedicated syntax\n\ The preferred way to construct a parameter specification is via the\n\
for generic functions, classes, and type aliases, where\n\ dedicated syntax for generic functions, classes, and type aliases,\n\
the use of '**' creates a parameter specification:\n\ where the use of '**' creates a parameter specification::\n\
\n\ \n\
type IntFunc[**P] = Callable[P, int]\n\ type IntFunc[**P] = Callable[P, int]\n\
\n\ \n\
For compatibility with Python 3.11 and earlier, ParamSpec objects\n\ For compatibility with Python 3.11 and earlier, ParamSpec objects\n\
can also be created as follows:\n\ can also be created as follows::\n\
\n\ \n\
P = ParamSpec('P')\n\ P = ParamSpec('P')\n\
\n\ \n\
Parameter specification variables exist primarily for the benefit of static\n\ Parameter specification variables exist primarily for the benefit of\n\
type checkers. They are used to forward the parameter types of one\n\ static type checkers. They are used to forward the parameter types of\n\
callable to another callable, a pattern commonly found in higher order\n\ one callable to another callable, a pattern commonly found in\n\
functions and decorators. They are only valid when used in ``Concatenate``,\n\ higher-order functions and decorators. They are only valid when used\n\
or as the first argument to ``Callable``, or as parameters for user-defined\n\ in ``Concatenate``, or as the first argument to ``Callable``, or as\n\
Generics. See class Generic for more information on generic types. An\n\ parameters for user-defined Generics. See class Generic for more\n\
example for annotating a decorator:\n\ information on generic types.\n\
\n\
An example for annotating a decorator::\n\
\n\ \n\
def add_logging[**P, T](f: Callable[P, T]) -> Callable[P, T]:\n\ def add_logging[**P, T](f: Callable[P, T]) -> Callable[P, T]:\n\
'''A type-safe decorator to add logging to a function.'''\n\ '''A type-safe decorator to add logging to a function.'''\n\
@ -966,12 +975,14 @@ example for annotating a decorator:\n\
'''Add two numbers together.'''\n\ '''Add two numbers together.'''\n\
return x + y\n\ return x + y\n\
\n\ \n\
Parameter specification variables can be introspected. e.g.:\n\ Parameter specification variables can be introspected. e.g.::\n\
\n\ \n\
P.__name__ == 'P'\n\ >>> P = ParamSpec(\"P\")\n\
>>> P.__name__\n\
'P'\n\
\n\ \n\
Note that only parameter specification variables defined in global scope can\n\ Note that only parameter specification variables defined in the global\n\
be pickled.\n\ scope can be pickled.\n\
"); ");
static PyType_Slot paramspec_slots[] = { static PyType_Slot paramspec_slots[] = {
@ -1167,34 +1178,35 @@ PyDoc_STRVAR(typevartuple_doc,
"Type variable tuple. A specialized form of type variable that enables\n\ "Type variable tuple. A specialized form of type variable that enables\n\
variadic generics.\n\ variadic generics.\n\
\n\ \n\
The preferred way to construct a type variable tuple is via the dedicated syntax\n\ The preferred way to construct a type variable tuple is via the\n\
for generic functions, classes, and type aliases, where a single\n\ dedicated syntax for generic functions, classes, and type aliases,\n\
'*' indicates a type variable tuple:\n\ where a single '*' indicates a type variable tuple::\n\
\n\ \n\
def move_first_element_to_last[T, *Ts](tup: tuple[T, *Ts]) -> tuple[*Ts, T]:\n\ def move_first_element_to_last[T, *Ts](tup: tuple[T, *Ts]) -> tuple[*Ts, T]:\n\
return (*tup[1:], tup[0])\n\ return (*tup[1:], tup[0])\n\
\n\ \n\
For compatibility with Python 3.11 and earlier, TypeVarTuple objects\n\ For compatibility with Python 3.11 and earlier, TypeVarTuple objects\n\
can also be created as follows:\n\ can also be created as follows::\n\
\n\ \n\
Ts = TypeVarTuple('Ts') # Can be given any name\n\ Ts = TypeVarTuple('Ts') # Can be given any name\n\
\n\ \n\
Just as a TypeVar (type variable) is a placeholder for a single type,\n\ Just as a TypeVar (type variable) is a placeholder for a single type,\n\
a TypeVarTuple is a placeholder for an *arbitrary* number of types. For\n\ a TypeVarTuple is a placeholder for an *arbitrary* number of types. For\n\
example, if we define a generic class using a TypeVarTuple:\n\ example, if we define a generic class using a TypeVarTuple::\n\
\n\ \n\
class C[*Ts]: ...\n\ class C[*Ts]: ...\n\
\n\ \n\
Then we can parameterize that class with an arbitrary number of type\n\ Then we can parameterize that class with an arbitrary number of type\n\
arguments:\n\ arguments::\n\
\n\ \n\
C[int] # Fine\n\ C[int] # Fine\n\
C[int, str] # Also fine\n\ C[int, str] # Also fine\n\
C[()] # Even this is fine\n\ C[()] # Even this is fine\n\
\n\ \n\
For more details, see PEP 646.\n\ For more details, see PEP 646.\n\
\n\ \n\
Note that only TypeVarTuples defined in global scope can be pickled.\n\ Note that only TypeVarTuples defined in the global scope can be\n\
pickled.\n\
"); ");
PyType_Slot typevartuple_slots[] = { PyType_Slot typevartuple_slots[] = {
@ -1436,21 +1448,21 @@ typealias_new_impl(PyTypeObject *type, PyObject *name, PyObject *value,
PyDoc_STRVAR(typealias_doc, PyDoc_STRVAR(typealias_doc,
"Type alias.\n\ "Type alias.\n\
\n\ \n\
Type aliases are created through the type statement:\n\ Type aliases are created through the type statement::\n\
\n\ \n\
type Alias = int\n\ type Alias = int\n\
\n\ \n\
In this example, Alias and int will be treated equivalently by static\n\ In this example, Alias and int will be treated equivalently by static\n\
type checkers.\n\ type checkers.\n\
\n\ \n\
At runtime, Alias is an instance of TypeAliasType. The __name__ attribute\n\ At runtime, Alias is an instance of TypeAliasType. The __name__\n\
holds the name of the type alias. The value of the type\n\ attribute holds the name of the type alias. The value of the type alias\n\
alias is stored in the __value__ attribute. It is evaluated lazily, so\n\ is stored in the __value__ attribute. It is evaluated lazily, so the\n\
the value is computed only if the attribute is accessed.\n\ value is computed only if the attribute is accessed.\n\
\n\ \n\
Type aliases can also be generic:\n\ Type aliases can also be generic::\n\
\n\ \n\
type ListOrSet[T] = list[T] | set[T]\n\ type ListOrSet[T] = list[T] | set[T]\n\
\n\ \n\
In this case, the type parameters of the alias are stored in the\n\ In this case, the type parameters of the alias are stored in the\n\
__type_params__ attribute.\n\ __type_params__ attribute.\n\
@ -1502,18 +1514,21 @@ _Py_make_typealias(PyThreadState* unused, PyObject *args)
PyDoc_STRVAR(generic_doc, PyDoc_STRVAR(generic_doc,
"Abstract base class for generic types.\n\ "Abstract base class for generic types.\n\
\n\ \n\
A generic type is typically declared by inheriting from\n\ On Python 3.12 and newer, generic classes implicitly inherit from\n\
this class parameterized with one or more type variables.\n\ Generic when they declare a parameter list after the class's name::\n\
For example, a generic mapping type might be defined as:\n\
\n\ \n\
class Mapping(Generic[KT, VT]):\n\ class Mapping[KT, VT]:\n\
def __getitem__(self, key: KT) -> VT:\n\ def __getitem__(self, key: KT) -> VT:\n\
...\n\ ...\n\
# Etc.\n\ # Etc.\n\
\n\ \n\
This class can then be used as follows:\n\ On older versions of Python, however, generic classes have to\n\
explicitly inherit from Generic.\n\
\n\ \n\
def lookup_name(mapping: Mapping[KT, VT], key: KT, default: VT) -> VT:\n\ After a class has been declared to be generic, it can then be used as\n\
follows::\n\
\n\
def lookup_name[KT, VT](mapping: Mapping[KT, VT], key: KT, default: VT) -> VT:\n\
try:\n\ try:\n\
return mapping[key]\n\ return mapping[key]\n\
except KeyError:\n\ except KeyError:\n\
@ -1523,12 +1538,12 @@ This class can then be used as follows:\n\
PyDoc_STRVAR(generic_class_getitem_doc, PyDoc_STRVAR(generic_class_getitem_doc,
"Parameterizes a generic class.\n\ "Parameterizes a generic class.\n\
\n\ \n\
At least, parameterizing a generic class is the *main* thing this method\n\ At least, parameterizing a generic class is the *main* thing this\n\
does. For example, for some generic class `Foo`, this is called when we\n\ method does. For example, for some generic class `Foo`, this is called\n\
do `Foo[int]` - there, with `cls=Foo` and `params=int`.\n\ when we do `Foo[int]` - there, with `cls=Foo` and `params=int`.\n\
\n\ \n\
However, note that this method is also called when defining generic\n\ However, note that this method is also called when defining generic\n\
classes in the first place with `class Foo(Generic[T]): ...`.\n\ classes in the first place with `class Foo[T]: ...`.\n\
"); ");
static PyObject * static PyObject *