Technical
Python Typing Protocols: Structural Interfaces Without The Boilerplate
I spent years writing abstract base classes in Python to define interfaces. It worked but felt wrong. Python is duck-typed, and ABCs fight the language. Protocols give me typed duck typing and changed how I structure code.
The Shape
A Protocol declares a shape. Any class with matching methods satisfies it, without inheritance. The type checker verifies the match at call sites.
from typing import Protocol
class Cache(Protocol):
def get(self, key: str) -> str | None: ...
def set(self, key: str, value: str, ttl: int) -> None: ...
class DynamoCache: # no inheritance
def get(self, key: str) -> str | None: ...
def set(self, key: str, value: str, ttl: int) -> None: ...
def serve(cache: Cache, key: str): ...
serve(DynamoCache(), 'home') # type checker says yesNo class DynamoCache(Cache). No import relationships. The contract is structural. You can swap implementations without the source file even knowing the protocol exists.
Why This Matters For Testing
Test doubles become dead simple. I write a FakeCache class with two methods and pass it in. No mock library. No patching. The type checker confirms the fake satisfies the protocol.
This is especially clean for external dependencies. I wrap third-party clients in a protocol, pass the protocol through my code, and use fakes in tests. The third-party library never appears in a test file.
When To Reach For It
Use Protocols when: you have more than one implementation, the implementations come from different modules, or you want to test with fakes. Skip Protocols when: there is only one implementation and no plan for another.
See PEP 544 for the formal definition. Structural types are the Python-native way to decouple. Once I started using them my ABC usage went to near zero.
RELATED READING
The Consulting Shift I Am Making In Year Two
After a year of writing and building, my consulting practice is changing shape. Shorter engagements. Sharper outcomes.
ReadThe Frontend Shift: Shipping Less JavaScript In Year Two
A year ago I reached for Next.js for everything. This year I often reach for nothing.
ReadThe Serverless Lesson I Would Write On A Sticky Note
After a year of shipping serverless projects, one rule explains most of the wins and all of the losses.
Read