Skip to content

Commit 39c07e8

Browse files
committed
Add text about Type[C]. (#218)
This addresses #107 (but it doen't close it because the issue also calls for an implementation in typing.py).
1 parent 6ab3abc commit 39c07e8

1 file changed

Lines changed: 95 additions & 0 deletions

File tree

‎pep-0484.txt‎

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -861,6 +861,101 @@ allow all operations on it, and a value of type ``Any`` can be assigned
861861
to a variable (or used as a return value) of a more constrained type.
862862

863863

864+
The type of class objects
865+
-------------------------
866+
867+
Sometimes you want to talk about class objects, in particular class
868+
objects that inherit from a given class. This can be spelled as
869+
``Type[C]`` where ``C`` is a class. To clarify: while ``C`` (when
870+
used as an annotation) refers to instances of class ``C``, ``Type[C]``
871+
refers to *subclasses* of ``C``. (This is a similar distinction as
872+
between ``object`` and ``type``.)
873+
874+
For example, suppose we have the following classes::
875+
876+
class User: ... # Abstract base for User classes
877+
class BasicUser(User): ...
878+
class ProUser(User): ...
879+
class TeamUser(User): ...
880+
881+
And suppose we have a function that creates an instance of one of
882+
these classes if you pass it a class object::
883+
884+
def new_user(user_class):
885+
user = user_class()
886+
# (Here we could write the user object to a database)
887+
return user
888+
889+
Without ``Type[]`` the best we could do to annotate ``new_user()``
890+
would be::
891+
892+
def new_user(user_class: type) -> User:
893+
...
894+
895+
However using ``Type[]`` and a type variable with an upper bound we
896+
can do much better::
897+
898+
U = TypeVar('U', bound=User)
899+
def new_user(user_class: Type[U]) -> U:
900+
...
901+
902+
Now when we call ``new_user()`` with a specific subclass of ``User`` a
903+
type checker will infer the correct type of the result::
904+
905+
joe = new_user(BasicUser) # Inferred type is BasicUser
906+
907+
The value corresponding to ``Type[C]`` must be an actual class object
908+
that's a subtype of ``C``, not a special form. IOW, in the above
909+
example calling e.g. ``new_user(Union[BasicUser, ProUser])`` is
910+
rejected by the type checker (in addition to failing at runtime
911+
because you can't instantiate a union).
912+
913+
Note that it is legal to use a union of classes as the parameter for
914+
``Type[]``, as in::
915+
916+
def new_non_team_user(user_class: Type[Union[BasicUser, ProUser]]):
917+
...
918+
919+
However the actual argument passed in at runtime must still be a
920+
concrete class object, e.g. in the above example::
921+
922+
new_non_team_user(ProUser) # OK
923+
new_non_team_user(TeamUser) # Disallowed by type checker
924+
925+
``Type[Any]`` is also supported (see below for its meaning). However,
926+
other special constructs like ``Tuple`` or ``Callable`` are not
927+
allowed.
928+
929+
There are some concerns with this feature: for example when
930+
``new_user()`` calls ``user_class()`` this implies that all subclasses
931+
of ``User`` must support this in their constructor signature. However
932+
this is not unique to ``Type[]``: class methods have similar concerns.
933+
A type checker ought to flag violations of such assumptions, but by
934+
default constructor calls that match the constructor signature in the
935+
indicated base class (``User`` in the example above) should be
936+
allowed. A program containing a complex or extensible class hierarchy
937+
might also handle this by using a factory class method. A future
938+
revision of this PEP may introduce better ways of dealing with these
939+
concerns.
940+
941+
When ``Type`` is parameterized it requires exactly one parameter.
942+
Plain ``Type`` without brackets is equivalent to ``Type[Any]`` and
943+
this in turn is equivalent to ``type`` (the root of Python's metaclass
944+
hierarchy). This equivalence also motivates the name, ``Type``, as
945+
opposed to alternatives like ``Class`` or ``SubType``, which were
946+
proposed while this feature was under discussion; this is similar to
947+
the relationship between e.g. ``List`` and ``list``.
948+
949+
Regarding the behavior of ``Type[Any]`` (or ``Type`` or ``type``),
950+
accessing attributes of a variable with this type only provides
951+
attributes and methods defined by ``type`` (for example,
952+
``__repr__()`` and ``__mro__``). Such a variable can be called with
953+
arbitrary arguments, and the return type is ``Any``.
954+
955+
``Type[T]`` should be considered covariant, since for a concrete class
956+
``C``, ``Type[C]`` matches ``C`` and any of its subclasses.
957+
958+
864959
Version and platform checking
865960
-----------------------------
866961

0 commit comments

Comments
 (0)