The type of class objects

(Freely after PEP 484: The type of class objects.)

Sometimes you want to talk about class objects that inherit from agiven class. This can be spelled as Type[C] where C is aclass. In other words, when C is the name of a class, using Cto annotate an argument declares that the argument is an instance ofC (or of a subclass of C), but using Type[C] as anargument annotation declares that the argument is a class objectderiving from C (or C itself).

For example, assume the following classes:

  1. class User:
  2. # Defines fields like name, email
  3.  
  4. class BasicUser(User):
  5. def upgrade(self):
  6. """Upgrade to Pro"""
  7.  
  8. class ProUser(User):
  9. def pay(self):
  10. """Pay bill"""

Note that ProUser doesn’t inherit from BasicUser.

Here’s a function that creates an instance of one of these classes ifyou pass it the right class object:

  1. def new_user(user_class):
  2. user = user_class()
  3. # (Here we could write the user object to a database)
  4. return user

How would we annotate this function? Without Type the best wecould do would be:

  1. def new_user(user_class: type) -> User:
  2. # Same implementation as before

This seems reasonable, except that in the following example, mypydoesn’t see that the buyer variable has type ProUser:

  1. buyer = new_user(ProUser)
  2. buyer.pay() # Rejected, not a method on User

However, using Type and a type variable with an upper bound (seeType variables with upper bounds) we can do better:

  1. U = TypeVar('U', bound=User)
  2.  
  3. def new_user(user_class: Type[U]) -> U:
  4. # Same implementation as before

Now mypy will infer the correct type of the result when we callnew_user() with a specific subclass of User:

  1. beginner = new_user(BasicUser) # Inferred type is BasicUser
  2. beginner.upgrade() # OK

Note

The value corresponding to Type[C] must be an actual classobject that’s a subtype of C. Its constructor must becompatible with the constructor of C. If C is a typevariable, its upper bound must be a class object.

For more details about Type[] see PEP 484: The type ofclass objects.