Protocols in Python. How to use structural subtyping | by Oliver S | Jul, 2023

How to use structural subtyping

Python 3.8 introduced a neat new feature: protocols. Protocols are an alternative to abstract base classes (ABC), and allow structural subtyping — checking whether two classes are compatible based on available attributes and functions alone. In this post we’ll go into the details about this and show how to use protocols using practical examples.

Photo by Chris Liverani on Unsplash

Let us begin by discussing how Python is typed. It is a dynamically typed language, meaning types are inferred at runtime and the following code runs without problems:

def add(x, y):
return x + y

print(add(2, 3))
print(add("str1", "str2"))

The first call results in an integer addition returning 5, the second in a string concatenation returning “str1str2”. This is different to e.g. C++, which is statically typed — and we have to provide type declarations:

int add(int x, int y) {
return x + y;

std::string add(std::string x, std::string y) {
return x + y;

int main()
std::cout<<add(2, 3);
std::cout << add("str1", "str2");
return 0;

Static typing offers the advantage of having the potential to catching errors at compile time — whereas in dynamically typed languages we only encounter these during runtime. On the other hand, dynamic typing can allow quicker prototyping and experimentation — one reason why Python has become so popular.

Dynamic typing is also called duck typing, based on the saying: “if it walks like a duck and it quacks like a duck, then it must be a duck”. Ergo: if objects offer the same attributes / functions, they should be treated similarly, and e.g. can be passed to functions requiring the other type.

Nevertheless, especially in larger, more professional software products, this unreliability offers more down- than upsides — and the trend thus goes towards static type checking, e.g. via providing type hints with mypy.


One interesting issue — hinted above e.g. in the short paragraph about duck typing — is subtyping. If we have a function with signature foo(x: X), what other classes except X does mypy allow to be passed to the function? (Note we now only…

Source link

Leave a Comment