In my article Python Type Checking I wrote about type hints. Type hints are around the block since Python 3.5.
Python 3.7 introduced another interesting concept to make Python code even more type safe: Protocols
If it walks like a duck and it quacks like a duck, then it must be a duck
Duck typing is a concept where an object isn’t characterized by its class type but by the presence of methods or attributes. Look at the following code:
class Foo: def render(self): return "foo" class Bar: def render(self): return 2 def render(obj): return "I have rendered: " + obj.render() render(Foo()) render(Bar())
Both classes Foo and Bar have a render method, so when I pass an instance of either class into the global render function the method can be called although Foo and Bar share no common base class.
This is of course a bit dangerous because with duck typing there is no way to determine the return type of a function.
Introduced with PEP 544 Protocols are a concept which is also called structural subtyping
Let’s take a closer look:
from typing import Protocol class Renderable(Protocol): def render(self) -> str: pass def render(obj: Renderable) -> str: return obj.render() class Foo: def render(self) -> str: return "foo" class Bar: def render(self) -> int: return 2 render(Foo()) render(Bar())
Before Python 3.7
If You are still working with older Python versions you can install the extension:
pip install typing-extensions
from typing_extensions import Protocol