Skip to content

Protocols

Protocols bring Python's duck-typing intuition into the static type world. They let you describe what an object can do rather than which base class it inherits from.

Quick takeaway: `Protocol` expresses interfaces structurally, by capability. It is especially valuable for test doubles, plugin points, and callback contracts.

Structural vs Nominal Typing

ABCs usually depend on explicit inheritance. Protocols depend on matching the required shape.

Basic Protocol Example

py
from typing import Protocol


class SupportsWrite(Protocol):
    def write(self, data: str) -> int: ...


def write_hello(target: SupportsWrite) -> int:
    return target.write("hello")

runtime_checkable Is a Helper, Not a Full Static Mirror

py
from typing import Protocol, runtime_checkable


@runtime_checkable
class Named(Protocol):
    name: str


class User:
    name = "jae"


print(isinstance(User(), Named))

`runtime_checkable` lets `isinstance()` participate, but it is not a perfect runtime replay of full static protocol analysis.

Why Callback Protocols Matter

  • They can express richer callback contracts than a plain Callable.
  • They help document extension points and event hooks.
  • They fit strategy objects and framework integration points well.

ABC vs Protocol

  • ABCs fit explicit runtime hierarchies.
  • Protocols fit loose structural compatibility.
  • They solve different design problems rather than competing directly.

Practical Connections

  • test doubles
  • pluggable interfaces
  • framework extension points

Official Sources

Built with VitePress for a Python 3.14 handbook.