← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Structural Subtyping with Protocol

python Python 3.8+ Intermediate

Also Known As

Protocol structural subtyping duck typing Python typing.Protocol runtime_checkable

TL;DR

Protocol classes define structural interfaces — any class with matching methods satisfies the protocol without explicit inheritance (type-safe duck typing).

Explanation

Protocol (typing.Protocol, Python 3.8+): a class satisfies a Protocol if it has all required attributes and methods, regardless of inheritance. Unlike ABC (which requires explicit subclassing), Protocol works at type-check time without modifying existing classes. @runtime_checkable enables isinstance() checks at runtime. Use for: typing third-party classes you cannot modify, documenting expected interfaces without coupling to a class hierarchy, and expressing duck types with static type safety.

Common Misconception

Protocol requires explicit registration like ABC — Protocol uses structural subtyping; any class with matching methods satisfies it at type-check time with no changes to the implementing class.

Why It Matters

Without Protocol, a function accepting any object with a read() method must use Any (loses type safety) or a custom ABC (requires modifying all implementing classes). Protocol gives type safety without coupling.

Common Mistakes

  • Using Protocol when ABC is more appropriate — use ABC when you want enforcement at class definition time
  • Not adding @runtime_checkable when isinstance() checks are needed
  • Protocol with mutable attributes — structural subtyping with mutable attributes can be surprising
  • Forgetting that satisfying the Protocol is checked at type-check time not runtime (without @runtime_checkable)

Code Examples

✗ Vulnerable
# Any type — loses all type safety:
def process(reader: Any) -> str:
    return reader.read()  # No type checking — any attribute access allowed

# ABC — requires modifying existing classes:
from abc import ABC, abstractmethod
class Readable(ABC):
    @abstractmethod
    def read(self) -> str: ...
# All implementing classes must inherit Readable — invasive coupling
✓ Fixed
from typing import Protocol, runtime_checkable

@runtime_checkable
class Readable(Protocol):
    def read(self) -> str: ...

def process(reader: Readable) -> str:
    return reader.read()  # Type-checked — must have read() -> str

# Any class with read() -> str satisfies it — no inheritance needed:
class FileReader:
    def read(self) -> str: return open(self.path).read()

class MockReader:
    def read(self) -> str: return 'mock data'

process(FileReader())  # Type-safe
process(MockReader())  # Type-safe
isinstance(MockReader(), Readable)  # True (runtime_checkable)

Added 16 Mar 2026
Edited 22 Mar 2026
Views 27
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
2 pings W 0 pings T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 1 ping S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 2 pings T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 1 ping W 0 pings T
No pings yet today
Amazonbot 6 Perplexity 5 ChatGPT 3 Unknown AI 3 Google 3 Ahrefs 1
crawler 20 crawler_json 1
DEV INTEL Tools & Severity
🟡 Medium ⚙ Fix effort: Medium
⚡ Quick Fix
Use Protocol to define structural interfaces in Python — any class with the required methods satisfies the Protocol without explicit inheritance, enabling PHP-style interface checking with Python's duck typing
📦 Applies To
python 3.8 web cli
🔗 Prerequisites
🔍 Detection Hints
ABC abstract base class with all abstract methods when Protocol would be simpler; type: ignore on duck-typed arguments
Auto-detectable: ✓ Yes mypy pyright pylance
⚠ Related Problems
🤖 AI Agent
Confidence: Low False Positives: Medium ✗ Manual fix Fix: Medium Context: Class

✓ schema.org compliant