The former is correct, if arg accepts an instance of CustomClass:
pythonCopydef FuncA(arg: CustomClass):
# ^ instance of CustomClass
In case you want the class CustomClass itself (or a subtype), then you should write:
pythonCopyfrom typing import Type # you have to import Type
def FuncA(arg: Type[CustomClass]):
# ^ CustomClass (class object) itself
Like it is written in the documentation about Typing:
pythonCopyclass typing.Type(Generic[CT_co])A variable annotated with
Cmay accept a value of typeC. In contrast, a variable annotated withType[C]may accept values that are classes themselves - specifically, it will accept the class object ofC.
The documentation includes an example with the int class:
pythonCopya = 3 # Has type 'int'
b = int # Has type 'Type[int]'
c = type(a) # Also has type 'Type[int]'
Update 2024: Type is now deprecated in favour of type
The former is correct, if arg accepts an instance of CustomClass:
pythonCopydef FuncA(arg: CustomClass):
# ^ instance of CustomClass
In case you want the class CustomClass itself (or a subtype), then you should write:
pythonCopyfrom typing import Type # you have to import Type
def FuncA(arg: Type[CustomClass]):
# ^ CustomClass (class object) itself
Like it is written in the documentation about Typing:
pythonCopyclass typing.Type(Generic[CT_co])A variable annotated with
Cmay accept a value of typeC. In contrast, a variable annotated withType[C]may accept values that are classes themselves - specifically, it will accept the class object ofC.
The documentation includes an example with the int class:
pythonCopya = 3 # Has type 'int'
b = int # Has type 'Type[int]'
c = type(a) # Also has type 'Type[int]'
Update 2024: Type is now deprecated in favour of type
Willem Van Onsem's answer is of course correct, but I'd like to offer a small update. In PEP 585, type hinting generics were introduced in standard collections. For example, whereas we previously had to say e.g.
pythonCopyfrom typing import Dict
foo: Dict[str, str] = { "bar": "baz" }
we can now forgo the parallel type hierarchy in the typing module and simply say
pythonCopyfoo: dict[str, str] = { "bar": "baz" }
This feature is available in python 3.9+, and also in 3.7+ if using from __future__ import annotations.
In terms of this specific question, it means that instead of from typing import Type, we can now simply annotate classes using the built-in type:
pythonCopydef FuncA(arg: type[CustomClass]):
I have two custom classes, one of which requires the other as an input argument.
class Authentication(object):
def __init__(self) -> None:
self.auth_data = self._resolve_auth()
class Data(object):
def __init__(self, authentication) -> None:
self.baseurl = authentication.baseurl
self.token = authentication.tokenI have the Authentication class defined in a seperate file in my project. So my question is, if I want to apply type-hinting to the Data class i.e.
def __init__(self, authentication: Authentication) -> None:
How do I go about doing this without having to import the Authentication class into my file which contains the Data class? It seems like overkill just to get proper type-hinting.
Videos
"self" references in type checking are typically done using strings:
class Node:
def append_child(self, node: 'Node'):
if node != None:
self.first_child = node
self.child_nodes += [node]
This is described in the "Forward references" section of PEP-0484.
Please note that this doesn't do any type-checking or casting. This is a type hint which python (normally) disregards completely1. However, third party tools (e.g. mypy), use type hints to do static analysis on your code and can generate errors before runtime.
Also, starting with python3.7, you can implicitly convert all of your type-hints to strings within a module by using the from __future__ import annotations (and in python4.0, this will be the default).
1The hints are introspectable -- So you could use them to build some kind of runtime checker using decorators or the like if you really wanted to, but python doesn't do this by default.
Postponed evaluation of annotations
PEP 563 introduced postponed evaluations in Python 3.7, stored in __annotations__ as strings. A user can enable this through the __future__ directive:
from __future__ import annotations
This makes it possible to write:
class C:
a: C
def foo(self, b: C):
...
This behaviour was originally planned to become mandatory in Python 4.0, then Python 3.10, but as of Python 3.13, it is still not mandatory. As of October 2024, no decision has been taken on when it will be mandatory.
Hello, Consider the code:
Class Spam:
@staticmethod
def make_spam(amount, animal_to_kill) -> Spam:
passAnd I'm getting NameError: name 'Spam' is not defined. I guess I cannot use a class name since it isn't fully definded. I know, I can live without fancy annotations, but...
As of May 2015, PEP 484 (Type Hints) has been formally accepted. The draft implementation is also available at github under ambv/typehinting.
In September 2015, Python 3.5 was released with support for Type Hints and includes a new typing module. This allows for the specification of types contained within collections. As of November 2015, JetBrains PyCharm 5.0 fully supports Python 3.5 to include Type Hints as illustrated below.

from typing import List
def do_something(l: List[str]):
for s in l:
s # str
Original Answer
As of Aug 2014, I have confirmed that it is not possible to use Python 3 type annotations to specify types within collections (ex: a list of strings).
The use of formatted docstrings such as reStructuredText or Sphinx are viable alternatives and supported by various IDEs.
It also appears that Guido is mulling over the idea of extending type annotations in the spirit of mypy: http://mail.python.org/pipermail/python-ideas/2014-August/028618.html
As of Python 3.9, builtin types are generic with respect to type annotations (see PEP 585). This allows to directly specify the type of elements:
def my_func(l: list[int]):
pass
This also extends to most other container types of the standard library, for example collections.deque or collections.abc.Mapping.
Various tools may support this syntax earlier than Python 3.9. When annotations are not inspected at runtime, the syntax is valid using quoting or __future__.annotations.
# quoted
def my_func(l: 'list[int]'):
pass
# postponed evaluation of annotation
from __future__ import annotations
def my_func(l: list[int]):
pass
As a consequence of PEP 585, most helpers in typing corresponding to standard library types are deprecated, such as typing.List, typing.Deque or typing.Mapping. They should only be used if compatibility with Python versions prior to 3.9 is required.