Skip to content

Commit 8c79274

Browse files
[3.11] Improve typing docs on the type of class objects (GH-106081) (#106097)
Improve typing docs on the type of class objects (GH-106081) (cherry picked from commit 3eeb8c8) Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
1 parent 1bbf60d commit 8c79274

File tree

1 file changed

+59
-49
lines changed

1 file changed

+59
-49
lines changed

Doc/library/typing.rst

Lines changed: 59 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,52 @@ of the same type ``T``, use ``tuple[T, ...]``. To denote an empty tuple, use
386386
z = (1, 2, 3)
387387
z = ()
388388

389+
.. _type-of-class-objects:
390+
391+
The type of class objects
392+
=========================
393+
394+
A variable annotated with ``C`` may accept a value of type ``C``. In
395+
contrast, a variable annotated with ``type[C]`` (or
396+
:class:`typing.Type[C] <Type>`) may accept values that are classes
397+
themselves -- specifically, it will accept the *class object* of ``C``. For
398+
example::
399+
400+
a = 3 # Has type ``int```
401+
b = int # Has type ``type[int]``
402+
c = type(a) # Also has type ``type[int]``
403+
404+
Note that ``type[C]`` is covariant::
405+
406+
class User: ...
407+
class ProUser(User): ...
408+
class TeamUser(User): ...
409+
410+
def make_new_user(user_class: type[User]) -> User:
411+
# ...
412+
return user_class()
413+
414+
make_new_user(User) # OK
415+
make_new_user(ProUser) # Also OK: ``type[ProUser]`` is a subtype of ``type[User]``
416+
make_new_user(TeamUser) # Still fine
417+
make_new_user(User()) # Error: expected ``type[User]`` but got ``User``
418+
make_new_user(int) # Error: ``type[int]`` is not a subtype of ``type[User]``
419+
420+
The only legal parameters for :class:`type` are classes, :data:`Any`,
421+
:ref:`type variables <generics>`, and unions of any of these types.
422+
For example::
423+
424+
def new_non_team_user(user_class: type[BasicUser | ProUser]): ...
425+
426+
new_non_team_user(BasicUser) # OK
427+
new_non_team_user(ProUser) # OK
428+
new_non_team_user(TeamUser) # Error: ``type[TeamUser]`` is not a subtype
429+
# of ``type[BasicUser | ProUser]``
430+
new_non_team_user(User) # Also an error
431+
432+
``type[Any]`` is equivalent to :class:`type`, which is the root of Python's
433+
:ref:`metaclass hierarchy <metaclasses>`.
434+
389435
.. _user-defined-generics:
390436

391437
User-defined generic types
@@ -1035,55 +1081,6 @@ These can be used as types in annotations. They all support subscription using
10351081
``ParamSpec`` and ``Concatenate``).
10361082
* :class:`ParamSpec` and :class:`Callable`.
10371083

1038-
1039-
.. class:: Type(Generic[CT_co])
1040-
1041-
Deprecated alias to :class:`type`.
1042-
1043-
A variable annotated with ``C`` may accept a value of type ``C``. In
1044-
contrast, a variable annotated with ``type[C]`` or ``Type[C]`` may accept values that are
1045-
classes themselves -- specifically, it will accept the *class object* of
1046-
``C``. For example::
1047-
1048-
a = 3 # Has type 'int'
1049-
b = int # Has type 'Type[int]'
1050-
c = type(a) # Also has type 'Type[int]'
1051-
1052-
Note that ``Type[C]`` is covariant::
1053-
1054-
class User: ...
1055-
class BasicUser(User): ...
1056-
class ProUser(User): ...
1057-
class TeamUser(User): ...
1058-
1059-
# Accepts User, BasicUser, ProUser, TeamUser, ...
1060-
def make_new_user(user_class: Type[User]) -> User:
1061-
# ...
1062-
return user_class()
1063-
1064-
The fact that ``Type[C]`` is covariant implies that all subclasses of
1065-
``C`` should implement the same constructor signature and class method
1066-
signatures as ``C``. The type checker should flag violations of this,
1067-
but should also allow constructor calls in subclasses that match the
1068-
constructor calls in the indicated base class. How the type checker is
1069-
required to handle this particular case may change in future revisions of
1070-
:pep:`484`.
1071-
1072-
The only legal parameters for :class:`Type` are classes, :data:`Any`,
1073-
:ref:`type variables <generics>`, and unions of any of these types.
1074-
For example::
1075-
1076-
def new_non_team_user(user_class: Type[BasicUser | ProUser]): ...
1077-
1078-
``Type[Any]`` is equivalent to ``Type`` which in turn is equivalent
1079-
to ``type``, which is the root of Python's metaclass hierarchy.
1080-
1081-
.. versionadded:: 3.5.2
1082-
1083-
.. deprecated:: 3.9
1084-
:class:`builtins.type <type>` now supports subscripting (``[]``).
1085-
See :pep:`585` and :ref:`types-genericalias`.
1086-
10871084
.. data:: Literal
10881085

10891086
Special typing form to define "literal types".
@@ -2838,6 +2835,19 @@ Aliases to built-in types
28382835
:class:`builtins.tuple <tuple>` now supports subscripting (``[]``).
28392836
See :pep:`585` and :ref:`types-genericalias`.
28402837

2838+
.. class:: Type(Generic[CT_co])
2839+
2840+
Deprecated alias to :class:`type`.
2841+
2842+
See :ref:`type-of-class-objects` for details on using :class:`type` or
2843+
``typing.Type`` in type annotations.
2844+
2845+
.. versionadded:: 3.5.2
2846+
2847+
.. deprecated:: 3.9
2848+
:class:`builtins.type <type>` now supports subscripting (``[]``).
2849+
See :pep:`585` and :ref:`types-genericalias`.
2850+
28412851
.. _corresponding-to-types-in-collections:
28422852

28432853
Aliases to types in :mod:`collections`

0 commit comments

Comments
 (0)