[Python-checkins] Improve typing docs on the type of class objects (#106081)
hauntsaninja
webhook-mailer at python.org
Mon Jun 26 03:13:51 EDT 2023
https://github.com/python/cpython/commit/3eeb8c89063d5ac22c0b1d26e4ae2fd12c149650
commit: 3eeb8c89063d5ac22c0b1d26e4ae2fd12c149650
branch: main
author: Alex Waygood <Alex.Waygood at Gmail.com>
committer: hauntsaninja <12621235+hauntsaninja at users.noreply.github.com>
date: 2023-06-26T00:13:48-07:00
summary:
Improve typing docs on the type of class objects (#106081)
files:
M Doc/library/typing.rst
diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst
index 9771ba0a794b3..7ac1062eb26d7 100644
--- a/Doc/library/typing.rst
+++ b/Doc/library/typing.rst
@@ -408,6 +408,52 @@ of the same type ``T``, use ``tuple[T, ...]``. To denote an empty tuple, use
z = (1, 2, 3)
z = ()
+.. _type-of-class-objects:
+
+The type of class objects
+=========================
+
+A variable annotated with ``C`` may accept a value of type ``C``. In
+contrast, a variable annotated with ``type[C]`` (or
+:class:`typing.Type[C] <Type>`) may accept values that are classes
+themselves -- specifically, it will accept the *class object* of ``C``. For
+example::
+
+ a = 3 # Has type ``int```
+ b = int # Has type ``type[int]``
+ c = type(a) # Also has type ``type[int]``
+
+Note that ``type[C]`` is covariant::
+
+ class User: ...
+ class ProUser(User): ...
+ class TeamUser(User): ...
+
+ def make_new_user(user_class: type[User]) -> User:
+ # ...
+ return user_class()
+
+ make_new_user(User) # OK
+ make_new_user(ProUser) # Also OK: ``type[ProUser]`` is a subtype of ``type[User]``
+ make_new_user(TeamUser) # Still fine
+ make_new_user(User()) # Error: expected ``type[User]`` but got ``User``
+ make_new_user(int) # Error: ``type[int]`` is not a subtype of ``type[User]``
+
+The only legal parameters for :class:`type` are classes, :data:`Any`,
+:ref:`type variables <generics>`, and unions of any of these types.
+For example::
+
+ def new_non_team_user(user_class: type[BasicUser | ProUser]): ...
+
+ new_non_team_user(BasicUser) # OK
+ new_non_team_user(ProUser) # OK
+ new_non_team_user(TeamUser) # Error: ``type[TeamUser]`` is not a subtype
+ # of ``type[BasicUser | ProUser]``
+ new_non_team_user(User) # Also an error
+
+``type[Any]`` is equivalent to :class:`type`, which is the root of Python's
+:ref:`metaclass hierarchy <metaclasses>`.
+
.. _user-defined-generics:
User-defined generic types
@@ -1093,55 +1139,6 @@ These can be used as types in annotations. They all support subscription using
``ParamSpec`` and ``Concatenate``).
* :class:`ParamSpec` and :class:`Callable`.
-
-.. class:: Type(Generic[CT_co])
-
- Deprecated alias to :class:`type`.
-
- A variable annotated with ``C`` may accept a value of type ``C``. In
- contrast, a variable annotated with ``type[C]`` or ``Type[C]`` may accept values that are
- classes themselves -- specifically, it will accept the *class object* of
- ``C``. For example::
-
- a = 3 # Has type 'int'
- b = int # Has type 'Type[int]'
- c = type(a) # Also has type 'Type[int]'
-
- Note that ``Type[C]`` is covariant::
-
- class User: ...
- class BasicUser(User): ...
- class ProUser(User): ...
- class TeamUser(User): ...
-
- # Accepts User, BasicUser, ProUser, TeamUser, ...
- def make_new_user(user_class: Type[User]) -> User:
- # ...
- return user_class()
-
- The fact that ``Type[C]`` is covariant implies that all subclasses of
- ``C`` should implement the same constructor signature and class method
- signatures as ``C``. The type checker should flag violations of this,
- but should also allow constructor calls in subclasses that match the
- constructor calls in the indicated base class. How the type checker is
- required to handle this particular case may change in future revisions of
- :pep:`484`.
-
- The only legal parameters for :class:`Type` are classes, :data:`Any`,
- :ref:`type variables <generics>`, and unions of any of these types.
- For example::
-
- def new_non_team_user(user_class: Type[BasicUser | ProUser]): ...
-
- ``Type[Any]`` is equivalent to ``Type`` which in turn is equivalent
- to ``type``, which is the root of Python's metaclass hierarchy.
-
- .. versionadded:: 3.5.2
-
- .. deprecated:: 3.9
- :class:`builtins.type <type>` now supports subscripting (``[]``).
- See :pep:`585` and :ref:`types-genericalias`.
-
.. data:: Literal
Special typing form to define "literal types".
@@ -3189,6 +3186,19 @@ Aliases to built-in types
:class:`builtins.tuple <tuple>` now supports subscripting (``[]``).
See :pep:`585` and :ref:`types-genericalias`.
+.. class:: Type(Generic[CT_co])
+
+ Deprecated alias to :class:`type`.
+
+ See :ref:`type-of-class-objects` for details on using :class:`type` or
+ ``typing.Type`` in type annotations.
+
+ .. versionadded:: 3.5.2
+
+ .. deprecated:: 3.9
+ :class:`builtins.type <type>` now supports subscripting (``[]``).
+ See :pep:`585` and :ref:`types-genericalias`.
+
.. _corresponding-to-types-in-collections:
Aliases to types in :mod:`collections`
More information about the Python-checkins
mailing list