["python","python-typing"]
How to annotate a type that's a class object (instead of a class instance)?

What is the proper way to annotate a function argument that expects a class object instead of an instance of that class? In the example below, some_class argument is expected to be a type instance (which is a class), but the problem here is that type is too broad: def construct(some_class: type, related_data:Dict[str, Any]) -> Any: ... In the case where some_class expects a specific set of types objects, using type does not help at all. The typing module might be in need of a Class generic that does this: def construct(some_class: Class[Union[Foo, Bar, Baz]], related_data:Dict[str, Any]) -> Union[Foo, Bar, Baz]: ... In the example above, some_class is the Foo, Bar or Faz class, not an instance of it. It should not matter their positions in the class tree because some_class: Class[Foo] should also be a valid case. Therefore, # classes are callable, so it is OK inst = some_class(**related_data) or # instances does not have __name__ clsname = some_class.__name__ or # an operation that only Foo, Bar and Baz can perform. some_class.a_common_classmethod() should be OK to mypy, pytype, PyCharm, etc. How can this be done with current implementation (Python 3.6 or earlier)?
To annotate an object that is a class, use typing.Type. For example, this would tell the type checker that some_class is class Foo or any of its subclasses: from typing import Type class Foo: ... class Bar(Foo): ... class Baz: ... some_class: Type[Foo] some_class = Foo # ok some_class = Bar # ok some_class = Baz # error some_class = Foo() # error Note that Type[Union[Foo, Bar, Baz]] and Union[Type[Foo], Type[Bar], Type[Baz]] are completely equivalent. If some_class could be any of a number of classes, you may want to make them all inherit from the same base class, and use Type[BaseClass]. Note that the inheritance must be non-virtual for now (mypy support for virtual inheritance is being discussed).