← Python lessons

Python Protocol: Structural Typing with runtime_checkable

A Python Protocol describes the methods an object must provide. Structural typing checks those methods without requiring a shared parent class.

Read Classes and objects and Type hints first.

Define a protocol

Inherit from Protocol and declare the required method signatures. ... stands in for the implementation.

from typing import Protocol

class Named(Protocol):
    def label(self) -> str:
        ...

def greet(item: Named) -> str:
    return f"Hello, {item.label()}"

A type checker expects arguments to greet() to have a compatible label() method.

Use a class without inheriting the protocol

A class matches through its methods. It does not need to inherit from Named.

from typing import Protocol

class Named(Protocol):
    def label(self) -> str:
        ...

class Player:
    def label(self) -> str:
        return "Ada"

def greet(item: Named) -> str:
    return f"Hello, {item.label()}"

print(greet(Player()))

This prints Hello, Ada. Type checkers compare the method's parameters and return type too.

Check member presence with runtime_checkable

Add @runtime_checkable to allow isinstance() checks against a protocol.

from typing import Protocol, runtime_checkable

@runtime_checkable
class Named(Protocol):
    def label(self) -> str:
        ...

class Player:
    def label(self) -> str:
        return "Ada"

print(isinstance(Player(), Named))
print(isinstance(42, Named))

This prints True and False.

Note: Runtime checks inspect member presence, not parameter or return types. They do not replace a type checker. Without @runtime_checkable, this isinstance() check raises TypeError.

See also: Type hints, Inheritance.

Your turn

Define a Bell class with a sound(self) -> str method returning "ding".

from typing import Protocol

class Audible(Protocol):
    def sound(self) -> str:
        ...

def announce(item: Audible) -> None:
    print(item.sound())

# add three lines: define Bell, define its sound method, then return "ding"
announce(Bell())

Expected output

ding

Practise this in the free Python course, where every exercise checks your code instantly.