Python 3.5 introduced Type Hints, a new feature that allows developers to use static type checking in python.
Type checking in Python
If it walks like a duck and it quacks like a duck, then it must be a duck.
Duck typing is a concept related to dynamic typing, where the type or the class of an object is less important than the methods it defines. When you use duck typing, you do not check types at all. Instead, you check for the presence of a given method or attribute.
In the following gist you can see an example that demonstrates how any object may be used in any context, up until it is used in a way that it is not supported:
Running the code above would result in the following output:
AttributeError: 'Whale' object has no attribute 'fly'
Duck and Sparrow are Flying animals because they know how to fly. Whale isn’t because it doesn’t :)
Static type checking in Python
Since Python 3.5 we can use the Type Hints to check the types in our python code. Now, we can write something similar like this:
In the example above we have defined a function that takes a string type parameter and returns a string value. Then, if we call the
greeting function we must pass a string value as parameter. We can assume that the returned value of the function will also be a string.
As its name suggests, the Type Hints are just that, hints, so we can write this code and run it without errors:
So, how we can check these hints? We must use a static type checker for this purpose. mypy is an optional static type checker for Python that aims to combine the benefits of duck typing and static typing. We can install mypy by running this command:
$ python -m pip install mypy
Once installed, we can check the last example:
$ mypy sample.py
sample.py:4: error: Argument 1 to "greeting" has incompatible type "int"; expected "str"
Found 1 error in 1 file (checked 1 source file)
As we can see an error is found because we are passing an integer value to the greeting function, which expected a string.
We can integrate this tool in our favorite editor and check these errors while coding. In Visual Studio Code, we can integrate it by installing the python extension and adding the
"python.linting.mypyEnabled": true line to the
.vscode/settings.json project file:
The most basic thing that we can do with the Type Hints is to assign types to variables using the built-in types:
Also, we can use the type hints for our functions, declaring the argument types but also the returned type:
Type hints can also be used with classes:
Declaring our own types
While we can use the built-in types in our projects, we can also declare our own.
With type aliases we can declare a type assigning an existing type to an alias. For example, we could declare a
Point type reusing the
Tuple[float, float] type:
typing module also includes the
NewType helper function that we can use to create distinct types. This function accepts two parameters: the name of the new type and the underlying type to use. In the following gist we refactored the last example in order to use the
There are some differences between using aliases or types defined with the
NewType helper. The use of a type alias declares two types to be equivalent to one another. Doing
Point = Tuple[float, float] will make the static type checker treat
Point as being exactly equivalent to
Tuple[float, float]. This is useful when you want to simplify complex type signatures. In contrast,
NewType declares one type to be a subtype of another. Doing
Point= NewType('Point', Tuple[float, float]) will make the static type checker treat
Point as a subclass of
Tuple[float, float], which means a value of type
Tuple[float, float] cannot be used in places where a value of type
Point is expected. This is useful when you want to prevent logic errors with minimal runtime cost.
Type Hints is a powerful feature that give us support to do type checking in our projects. This can help us to avoid code mistakes and it’s also useful to better understand the intent of the code.