Python Type Hints - Duck typing with Protocol2021-05-18
Duck typing says “if it quacks like a duck, treat it like a duck.”
Type checking seems at odds with duck typing: we restrict variables to named types (classes), allowing only that type or subtypes.
This seems like it would stop us from passing in arbitrary objects that can “quack the right way”.
But since PEP 0544, we can declare “duckish” types with
Take this example:
Here we have a vanilla
Duck class and a function that accepts that class.
sonorize() is quite restrictive, and could better serve users by being duck-typed.
It could accept anything with a correctly typed
quack() method and function just fine.
The way to specify this is with a
A protocol type contains a set of typed methods and variables.
If an object has those methods and variables, it will match the protocol type.
typing.Protocol was added in Python 3.8.
On prior versions of Python, you can use
typing_extensions.Protocol, and migrate when you upgrade.
Mypy has supported
Protocol since version 0.530 (October 2017).
In our example, we can define a protocol for objects that can quack:
class syntax to define a protocol, and add relevant members in the body with type hints.
The methods will never be executed, so it’s standard to use Python’s ellipsis symbol for their bodies.
With the protocol defined, we can use it in
sonorize() to match any object with a
quack() method that returns a string.
To combine it into a full example:
The Python documentation calls use of
Protocol structural subtyping, meaning the type checker compares types based upon their internal structure.
This is opposed to nominal subtyping, meaning that the type checker compares types based on whether they are the named type, or a subclass.
The abstract base classes in Python’s
collections.abc module are useful for common protocol checks.
For example, you can use
Sized to accept any type that works with
Iterable[int] to accept any iterable of integers.
May types help you get all your ducks in a row,
Want better tests? Check out my book Speed Up Your Django Tests which teaches you to write faster, more accurate tests.
One summary email a week, no spam, I pinky promise.
- Python Type Hints - How to Specify a Class Rather Than an Instance Thereof
- Python Type Hints - How to Use TypedDict
- Python Type Hints - How to Fix Circular Imports
Tags: mypy, python
© 2021 All rights reserved.