8000 Improve typing docs on the type of class objects (#106081) · python/cpython@3eeb8c8 · GitHub
[go: up one dir, main page]

Skip to content

Commit 3eeb8c8

Browse files
authored
Improve typing docs on the type of class objects (#106081)
1 parent 7ca8716 commit 3eeb8c8

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
@@ -408,6 +408,52 @@ of the same type ``T``, use ``tuple[T, ...]``. To denote an empty tuple, use
408408
z = (1, 2, 3)
409409
z = ()
410410

411+
.. _type-of-class-objects:
412+
413+
The type of class objects
414+
=========================
415+
416+
A variable annotated with ``C`` may accept a value of type ``C``. In
417+
contrast, a variable annotated with ``type[C]`` (or
418+
:class:`typing.Type[C] <Type>`) may accept values that are classes
419+
themselves -- specifically, it will accept the *class object* of ``C``. For
420+
example::
421+
422+
a = 3 # Has type ``int```
423+
b = int # Has type ``type[int]``
424+
c = type(a) # Also has type ``type[int]``
425+
426+
Note that ``type[C]`` is covariant::
427+
428+
class User: ...
429+
class ProUser(User): ...
430+
class TeamUser(User): ...
431+
432+
def make_new_user(user_class: type[User]) -> User:
433+
# ...
434+
return user_class()
435+
436+
make_new_user(User) # OK
437+
make_new_user(ProUser) # Also OK: ``type[ProUser]`` is a subtype of ``type[User]``
438+
make_new_user(TeamUser) # Still fine
439+
make_new_user(User()) # Error: expected ``type[User]`` but got ``User``
440+
make_new_user(int) # Error: ``type[int]`` is not a subtype of ``type[User]``
441+
442+
The only legal parameters for :class:`type` are classes, :data:`Any`,
443+
:ref:`type variables <generics>`, and unions of any of these types.
444+
For example::
445+
446+
def new_non_team_user(user_class: type[BasicUser | ProUser]): ...
447+
448+
new_non_team_user(BasicUser) # OK
449+
new_non_team_user(ProUser) # OK
450+
new_non_team_user(TeamUser) # Error: ``type[TeamUser]`` is not a subtype
451+
# of ``type[BasicUser | ProUser]``
452+
new_non_team_user(User) # Also an error
453+
454+
``type[Any]`` is equivalent to :class:`type`, which is the root of Python's
455+
:ref:`metaclass hierarchy <metaclasses>`.
456+
411457
.. _user-defined-generics:
412458

413459
User-defined generic types
@@ -1093,55 +1139,6 @@ These can be used as types in annotations. They all support subscription using
10931139
``ParamSpec`` and ``Concatenate``).
10941140
* :class:`ParamSpec` and :class:`Callable`.
10951141

1096-
1097-
.. class:: Type(Generic[CT_co])
1098-
1099-
Deprecated alias to :class:`type`.
1100-
1101-
A variable annotated with ``C`` may accept a value of type ``C``. In
1102-
contrast, a variable annotated with ``type[C]`` or ``Type[C]`` may accept values that are
1103-
classes themselves -- specifically, it will accept the *class object* of
1104-
``C``. For example::
1105-
1106-
a = 3 # Has type 'int'
1107-
b = int # Has type 'Type[int]'
1108-
c = type(a) # Also has type 'Type[int]'
1109-
1110-
Note that ``Type[C]`` is covariant::
1111-
1112-
class User: ...
1113-
class BasicUser(User): ...
1114-
class ProUser(User): ...
1115-
class TeamUser(User): ...
1116-
1117-
# Accepts User, BasicUser, ProUser, TeamUser, ...
1118-
def make_new_user(user_class: Type[User]) -> User:
1119-
# ...
1120-
return user_class()
1121-
1122-
The fact that ``Type[C]`` is covariant implies that all subclasses of
1123-
``C`` should implement the same constructor signature and class method
1124-
signatures as ``C``. The type checker should flag violations of this,
1125-
but should also allow constructor calls in subclasses that match the
1126-
constructor calls in the indicated base class. How the type checker is
1127-
required to handle this particular case may change in future revisions of
1128-
:pep:`484`.
1129-
1130-
The only legal parameters for :class:`Type` are classes, :data:`Any`,
1131-
:ref:`type variables <generics>`, and unions of any of these types.
1132-
For example::
1133-
1134-
def new_non_team_user(user_class: Type[BasicUser | ProUser]): ...
1135-
1136-
``Type[Any]`` is equivalent to ``Type`` which in turn is equivalent
1137-
to ``type``, which is the root of Python's metaclass hierarchy.
1138-
1139-
.. versionadded:: 3.5.2
1140-
1141-
.. deprecated:: 3.9
1142-
:class:`builtins.type <type>` now supports subscripting (``[]``).
1143-
See :pep:`585` and :ref:`types-genericalias`.
1144-
11451142
.. data:: Literal
11461143

11471144
Special typing form to define "literal types".
@@ -3189,6 +3186,19 @@ Aliases to built-in types
31893186
:class:`builtins.tuple <tuple>` now supports subscripting (``[]``).
31903187
See :pep:`585` and :ref:`types-genericalias`.
31913188

3189+
.. class:: Type(Generic[CT_co])
3190+
3191+
Deprecated alias to :class:`type`.
3192+
3193+
See :ref:`type-of-class-objects` for details on using :class:`type` or
3194+
``typing.Type`` in type annotations.
3195+
3196+
.. versionadded:: 3.5.2
3197+
3198+
.. deprecated:: 3.9
3199+
:class:`builtins.type <type>` now supports subscripting (``[]``).
3200+
See :pep:`585` and :ref:`types-genericalias`.
3201+
31923202
.. _corresponding-to-types-in-collections:
31933203

31943204
Aliases to types in :mod:`collections`

0 commit comments

Comments
 (0)
0