diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 0a7b77f4415..949b108c60c 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -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: ... -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 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 - ``AnyStr`` is a :ref:`constrained type variable ` defined as - ``AnyStr = TypeVar('AnyStr', str, bytes)``. + A :ref:`constrained type variable `. - 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:: + Definition:: + + 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: 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 + concat("foo", "bar") # OK, output has type 'str' + concat(b"foo", b"bar") # OK, output has type 'bytes' + concat("foo", b"bar") # Error, cannot mix str and bytes .. 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 - ``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 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: - run_query("SELECT * FROM students") # ok - run_query(literal_string) # ok - run_query("SELECT * FROM " + literal_string) # ok + run_query("SELECT * FROM students") # OK + run_query(literal_string) # OK + run_query("SELECT * FROM " + literal_string) # OK run_query(arbitrary_string) # type checker error run_query( # type checker error 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 that generate type checker errors could be vulnerable to an SQL injection attack. @@ -766,7 +770,7 @@ These can be used as types in annotations and do not support ``[]``. case str(): print("It's a str") case _: - never_call_me(arg) # ok, arg is of type Never + never_call_me(arg) # OK, arg is of type Never .. versionadded:: 3.11 @@ -776,6 +780,7 @@ These can be used as types in annotations and do not support ``[]``. .. data:: NoReturn Special type indicating that a function never returns. + For example:: from typing import NoReturn @@ -795,6 +800,7 @@ These can be used as types in annotations and do not support ``[]``. .. data:: Self Special type to represent the current enclosed class. + For example:: from typing import Self @@ -943,8 +949,6 @@ These can be used as types in annotations using ``[]``, each having a unique syn .. data:: Optional - Optional type. - ``Optional[X]`` is equivalent to ``X | None`` (or ``Union[X, None]``). 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 - Used with :data:`Callable` and :class:`ParamSpec` to type annotate a higher - order callable which adds, removes, or transforms parameters of another + Special form for annotating higher-order functions. + + ``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 ``Concatenate[Arg1Type, Arg2Type, ..., ParamSpecVariable]``. ``Concatenate`` 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 - A type that can be used to indicate to type checkers that the - corresponding variable or function parameter has a value equivalent to - the provided literal (or one of several literals). For example:: + Special typing form to define "literal types". + + ``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 ... - MODE = Literal['r', 'rb', 'w', 'wb'] - def open_helper(file: str, mode: MODE) -> str: + type Mode = Literal['r', 'rb', 'w', 'wb'] + 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 ``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 - A special typing construct to indicate to type checkers that a name - cannot be re-assigned or overridden in a subclass. For example:: + Special typing construct to indicate final names to type checkers. + + 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 += 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 + 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 - Special typing constructs that mark individual keys of a :class:`TypedDict` - as either required or non-required respectively. + Special typing construct to mark a :class:`TypedDict` key as potentially + missing. 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 - 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. 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 - A typing operator that conceptually marks an object as having been - unpacked. For example, using the unpack operator ``*`` on a + Typing operator to conceptually mark an object as having been unpacked. + + For example, using the unpack operator ``*`` on a :class:`type variable tuple ` is equivalent to using ``Unpack`` 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. Calling :func:`get_origin` on either of these objects will return the - original ``ParamSpec``:: + original ``ParamSpec``: - P = ParamSpec("P") - get_origin(P.args) # returns P - get_origin(P.kwargs) # returns P + .. doctest:: + + >>> from typing import ParamSpec + >>> P = ParamSpec("P") + >>> get_origin(P.args) is P + True + >>> get_origin(P.kwargs) is P + True .. versionadded:: 3.10 @@ -2010,13 +2040,15 @@ These are not used in annotations. They are building blocks for declaring types. .. 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. + Helper class to create low-overhead :ref:`distinct types `. + + A ``NewType`` is considered a distinct type by a typechecker. At runtime, + however, calling a ``NewType`` returns its argument unchanged. + Usage:: - UserId = NewType('UserId', int) - first_user = UserId(1) + UserId = NewType('UserId', int) # Declare the NewType "UserId" + first_user = UserId(1) # "UserId" returns the argument unchanged at runtime .. attribute:: __module__ @@ -2037,7 +2069,9 @@ These are not used in annotations. They are building blocks for declaring types. .. 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): def meth(self) -> int: @@ -2478,11 +2512,12 @@ Other concrete types .. class:: Pattern Match - These type aliases - correspond to the return types from :func:`re.compile` and - :func:`re.match`. These types (and the corresponding functions) - are generic in ``AnyStr`` and can be made specific by writing - ``Pattern[str]``, ``Pattern[bytes]``, ``Match[str]``, or + Deprecated aliases corresponding to the return types from + :func:`re.compile` and :func:`re.match`. + + These types (and the corresponding functions) are generic over + :data:`AnyStr`. ``Pattern`` can be specialised as ``Pattern[str]`` or + ``Pattern[bytes]``; ``Match`` can be specialised as ``Match[str]`` or ``Match[bytes]``. .. deprecated:: 3.9 @@ -2491,7 +2526,9 @@ Other concrete types .. 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 ``unicode``. @@ -2568,6 +2605,7 @@ Corresponding to collections in :mod:`collections.abc` .. class:: Mapping(Collection[KT], Generic[KT, VT_co]) Deprecated alias to :class:`collections.abc.Mapping`. + This type can be used as follows:: def get_position_in_index(word_list: Mapping[str, int], word: str) -> int: @@ -2919,6 +2957,7 @@ Functions and decorators last case can never execute, because ``arg`` is either an :class:`int` or a :class:`str`, and both options are covered by earlier cases. + If a type checker finds that a call to ``assert_never()`` is reachable, it will emit an error. For example, if the type annotation for ``arg`` was instead ``int | str | float``, the type checker would @@ -2969,11 +3008,14 @@ Functions and decorators .. 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. The presence of ``@dataclass_transform()`` tells a static type checker that the 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: @@ -3074,16 +3116,22 @@ Functions and decorators .. decorator:: overload + Decorator for creating overloaded functions and methods. + The ``@overload`` decorator allows describing functions and methods that support multiple different combinations of argument types. A series of ``@overload``-decorated definitions must be followed by exactly one 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 - 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 - a ``@overload``-decorated function directly will raise - :exc:`NotImplementedError`. An example of overload that gives a more + an ``@overload``-decorated function directly will raise + :exc:`NotImplementedError`. + + An example of overload that gives a more precise type than can be expressed using a union or a type variable: .. testcode:: @@ -3110,7 +3158,9 @@ Functions and decorators .. function:: get_overloads(func) Return a sequence of :func:`@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 the documentation for :func:`@overload `, ``get_overloads(process)`` will return a sequence of three function objects @@ -3125,16 +3175,21 @@ Functions and decorators .. function:: clear_overloads() - Clear all registered overloads in the internal registry. This can be used - to reclaim the memory used by the registry. + Clear all registered overloads in the internal registry. + + This can be used to reclaim the memory used by the registry. .. versionadded:: 3.11 .. decorator:: final - A decorator to indicate to type checkers that the decorated method - cannot be overridden, and the decorated class cannot be subclassed. + Decorator to indicate final methods and final classes. + + 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:: class Base: @@ -3157,7 +3212,7 @@ Functions and decorators .. versionadded:: 3.8 .. 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 ``if getattr(obj, "__final__", False)`` can be used at runtime to determine whether an object ``obj`` has been marked as final. @@ -3169,11 +3224,13 @@ Functions and decorators 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 - (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 @@ -3185,8 +3242,11 @@ Functions and decorators .. decorator:: override - A decorator for methods that indicates to type checkers that this method - should override a method or attribute with the same name on a base class. + Decorator to indicate that a method in a subclass is intended to override a + 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 an equivalent change to a child class. @@ -3209,7 +3269,7 @@ Functions and decorators 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 ``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 @@ -3223,7 +3283,7 @@ Functions and decorators .. 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 intended to mark classes that are defined in type stub files if @@ -3277,6 +3337,7 @@ Introspection helpers .. versionchanged:: 3.9 Added ``include_extras`` parameter as part of :pep:`593`. + See the documentation on :data:`Annotated` for more information. .. versionchanged:: 3.11 Previously, ``Optional[t]`` was added for function and method annotations @@ -3286,11 +3347,14 @@ Introspection helpers .. function:: get_origin(tp) 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 - :mod:`collections` class, it gets normalized to the original class. + ``X[Y, Z, ...]`` return ``X``. + + 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`, return the underlying :class:`ParamSpec`. Return ``None`` for unsupported objects. + Examples: .. testcode:: @@ -3308,10 +3372,12 @@ Introspection helpers Get type arguments with all substitutions performed: for a typing object of the form ``X[Y, Z, ...]`` return ``(Y, Z, ...)``. + If ``X`` is a union or :class:`Literal` contained in another generic type, the order of ``(Y, Z, ...)`` may be different from the order of the original arguments ``[Y, Z, ...]`` due to type caching. Return ``()`` for unsupported objects. + Examples: .. testcode:: @@ -3345,9 +3411,10 @@ Introspection helpers .. 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 - ``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. .. note:: @@ -3363,7 +3430,9 @@ Constant .. data:: TYPE_CHECKING 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: import expensive_mod diff --git a/Lib/typing.py b/Lib/typing.py index 6f853363e58..a531e7d7abb 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -561,7 +561,7 @@ def Never(self, parameters): case str(): print("It's a str") 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") @@ -594,13 +594,13 @@ def LiteralString(self, parameters): from typing import LiteralString - def run_query(sql: LiteralString) -> ... + def run_query(sql: LiteralString) -> None: ... def caller(arbitrary_string: str, literal_string: LiteralString) -> None: - run_query("SELECT * FROM students") # ok - run_query(literal_string) # ok - run_query("SELECT * FROM " + literal_string) # ok + run_query("SELECT * FROM students") # OK + run_query(literal_string) # OK + run_query("SELECT * FROM " + literal_string) # OK run_query(arbitrary_string) # type checker error run_query( # type checker error f"SELECT * FROM students WHERE name = {arbitrary_string}" @@ -2118,7 +2118,7 @@ def assert_type(val, typ, /): emits an error if the value is not of the specified type:: def greet(name: str) -> None: - assert_type(name, str) # ok + assert_type(name, str) # OK assert_type(name, int) # type checker error """ return val diff --git a/Objects/typevarobject.c b/Objects/typevarobject.c index 0b7d84c706d..406a6eb76e3 100644 --- a/Objects/typevarobject.c +++ b/Objects/typevarobject.c @@ -443,23 +443,25 @@ static PyMethodDef typevar_methods[] = { PyDoc_STRVAR(typevar_doc, "Type variable.\n\ \n\ -The preferred way to construct a type variable is via the dedicated syntax\n\ -for generic functions, classes, and type aliases:\n\ +The preferred way to construct a type variable is via the dedicated\n\ +syntax for generic functions, classes, and type aliases::\n\ \n\ class Sequence[T]: # T is a TypeVar\n\ ...\n\ \n\ This syntax can also be used to create bound and constrained type\n\ -variables:\n\ +variables::\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\ - 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\ However, if desired, reusable type variables can also be constructed\n\ -manually, like so:\n\ +manually, like so::\n\ \n\ T = TypeVar('T') # Can be anything\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\ as for generic function and type alias definitions.\n\ \n\ -The variance of type variables is inferred by type checkers when they are created\n\ -through the type parameter syntax and when ``infer_variance=True`` is passed.\n\ -Manually created type variables may be explicitly marked covariant or\n\ -contravariant by passing ``covariant=True`` or ``contravariant=True``.\n\ -By default, manually created type variables are invariant. See PEP 484\n\ -and PEP 695 for more details.\n\ +The variance of type variables is inferred by type checkers when they\n\ +are created through the type parameter syntax and when\n\ +``infer_variance=True`` is passed. Manually created type variables may\n\ +be explicitly marked covariant or contravariant by passing\n\ +``covariant=True`` or ``contravariant=True``. By default, manually\n\ +created type variables are invariant. See PEP 484 and PEP 695 for more\n\ +details.\n\ "); static PyType_Slot typevar_slots[] = { @@ -616,12 +619,14 @@ PyDoc_STRVAR(paramspecargs_doc, \n\ Given a ParamSpec object P, P.args is an instance of ParamSpecArgs.\n\ \n\ -ParamSpecArgs objects have a reference back to their ParamSpec:\n\ +ParamSpecArgs objects have a reference back to their ParamSpec::\n\ \n\ - P.args.__origin__ is P\n\ + >>> P = ParamSpec(\"P\")\n\ + >>> P.args.__origin__ is P\n\ + True\n\ \n\ -This type is meant for runtime introspection and has no special meaning to\n\ -static type checkers.\n\ +This type is meant for runtime introspection and has no special meaning\n\ +to static type checkers.\n\ "); static PyType_Slot paramspecargs_slots[] = { @@ -693,12 +698,14 @@ PyDoc_STRVAR(paramspeckwargs_doc, \n\ Given a ParamSpec object P, P.kwargs is an instance of ParamSpecKwargs.\n\ \n\ -ParamSpecKwargs objects have a reference back to their ParamSpec:\n\ +ParamSpecKwargs objects have a reference back to their ParamSpec::\n\ \n\ - P.kwargs.__origin__ is P\n\ + >>> P = ParamSpec(\"P\")\n\ + >>> P.kwargs.__origin__ is P\n\ + True\n\ \n\ -This type is meant for runtime introspection and has no special meaning to\n\ -static type checkers.\n\ +This type is meant for runtime introspection and has no special meaning\n\ +to static type checkers.\n\ "); static PyType_Slot paramspeckwargs_slots[] = { @@ -935,24 +942,26 @@ static PyMethodDef paramspec_methods[] = { PyDoc_STRVAR(paramspec_doc, "Parameter specification variable.\n\ \n\ -The preferred way to construct a parameter specification is via the dedicated syntax\n\ -for generic functions, classes, and type aliases, where\n\ -the use of '**' creates a parameter specification:\n\ +The preferred way to construct a parameter specification is via the\n\ +dedicated syntax for generic functions, classes, and type aliases,\n\ +where the use of '**' creates a parameter specification::\n\ \n\ type IntFunc[**P] = Callable[P, int]\n\ \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\ P = ParamSpec('P')\n\ \n\ -Parameter specification variables exist primarily for the benefit of static\n\ -type checkers. They are used to forward the parameter types of one\n\ -callable to another callable, a pattern commonly found in higher order\n\ -functions and decorators. They are only valid when used in ``Concatenate``,\n\ -or as the first argument to ``Callable``, or as parameters for user-defined\n\ -Generics. See class Generic for more information on generic types. An\n\ -example for annotating a decorator:\n\ +Parameter specification variables exist primarily for the benefit of\n\ +static type checkers. They are used to forward the parameter types of\n\ +one callable to another callable, a pattern commonly found in\n\ +higher-order functions and decorators. They are only valid when used\n\ +in ``Concatenate``, or as the first argument to ``Callable``, or as\n\ +parameters for user-defined Generics. See class Generic for more\n\ +information on generic types.\n\ +\n\ +An example for annotating a decorator::\n\ \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\ @@ -966,12 +975,14 @@ example for annotating a decorator:\n\ '''Add two numbers together.'''\n\ return x + y\n\ \n\ -Parameter specification variables can be introspected. e.g.:\n\ +Parameter specification variables can be introspected. e.g.::\n\ \n\ - P.__name__ == 'P'\n\ + >>> P = ParamSpec(\"P\")\n\ + >>> P.__name__\n\ + 'P'\n\ \n\ -Note that only parameter specification variables defined in global scope can\n\ -be pickled.\n\ +Note that only parameter specification variables defined in the global\n\ +scope can be pickled.\n\ "); 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\ variadic generics.\n\ \n\ -The preferred way to construct a type variable tuple is via the dedicated syntax\n\ -for generic functions, classes, and type aliases, where a single\n\ -'*' indicates a type variable tuple:\n\ +The preferred way to construct a type variable tuple is via the\n\ +dedicated syntax for generic functions, classes, and type aliases,\n\ +where a single '*' indicates a type variable tuple::\n\ \n\ def move_first_element_to_last[T, *Ts](tup: tuple[T, *Ts]) -> tuple[*Ts, T]:\n\ return (*tup[1:], tup[0])\n\ \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\ - Ts = TypeVarTuple('Ts') # Can be given any name\n\ + Ts = TypeVarTuple('Ts') # Can be given any name\n\ \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\ -example, if we define a generic class using a TypeVarTuple:\n\ +example, if we define a generic class using a TypeVarTuple::\n\ \n\ - class C[*Ts]: ...\n\ + class C[*Ts]: ...\n\ \n\ Then we can parameterize that class with an arbitrary number of type\n\ -arguments:\n\ +arguments::\n\ \n\ - C[int] # Fine\n\ - C[int, str] # Also fine\n\ - C[()] # Even this is fine\n\ + C[int] # Fine\n\ + C[int, str] # Also fine\n\ + C[()] # Even this is fine\n\ \n\ For more details, see PEP 646.\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[] = { @@ -1436,21 +1448,21 @@ typealias_new_impl(PyTypeObject *type, PyObject *name, PyObject *value, PyDoc_STRVAR(typealias_doc, "Type alias.\n\ \n\ -Type aliases are created through the type statement:\n\ +Type aliases are created through the type statement::\n\ \n\ - type Alias = int\n\ + type Alias = int\n\ \n\ In this example, Alias and int will be treated equivalently by static\n\ type checkers.\n\ \n\ -At runtime, Alias is an instance of TypeAliasType. The __name__ attribute\n\ -holds the name of the type alias. The value of the type\n\ -alias is stored in the __value__ attribute. It is evaluated lazily, so\n\ -the value is computed only if the attribute is accessed.\n\ +At runtime, Alias is an instance of TypeAliasType. The __name__\n\ +attribute holds the name of the type alias. The value of the type alias\n\ +is stored in the __value__ attribute. It is evaluated lazily, so the\n\ +value is computed only if the attribute is accessed.\n\ \n\ -Type aliases can also be generic:\n\ +Type aliases can also be generic::\n\ \n\ - type ListOrSet[T] = list[T] | set[T]\n\ + type ListOrSet[T] = list[T] | set[T]\n\ \n\ In this case, the type parameters of the alias are stored in the\n\ __type_params__ attribute.\n\ @@ -1502,18 +1514,21 @@ _Py_make_typealias(PyThreadState* unused, PyObject *args) PyDoc_STRVAR(generic_doc, "Abstract base class for generic types.\n\ \n\ -A generic type is typically declared by inheriting from\n\ -this class parameterized with one or more type variables.\n\ -For example, a generic mapping type might be defined as:\n\ +On Python 3.12 and newer, generic classes implicitly inherit from\n\ +Generic when they declare a parameter list after the class's name::\n\ \n\ - class Mapping(Generic[KT, VT]):\n\ + class Mapping[KT, VT]:\n\ def __getitem__(self, key: KT) -> VT:\n\ ...\n\ # Etc.\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\ - 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\ return mapping[key]\n\ except KeyError:\n\ @@ -1523,12 +1538,12 @@ This class can then be used as follows:\n\ PyDoc_STRVAR(generic_class_getitem_doc, "Parameterizes a generic class.\n\ \n\ -At least, parameterizing a generic class is the *main* thing this method\n\ -does. For example, for some generic class `Foo`, this is called when we\n\ -do `Foo[int]` - there, with `cls=Foo` and `params=int`.\n\ +At least, parameterizing a generic class is the *main* thing this\n\ +method does. For example, for some generic class `Foo`, this is called\n\ +when we do `Foo[int]` - there, with `cls=Foo` and `params=int`.\n\ \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 *