Lab 10: Protocol Typing

Time: 60 minutes | Level: Architect | Docker: docker run -it --rm python:3.11-slim bash

Overview

Python's typing.Protocol enables structural subtyping ("duck typing" with static type checking). This lab covers Protocol, ParamSpec, TypeVarTuple, Concatenate, variance, and overload for building type-safe, flexible APIs.

Step 1: typing.Protocol — Structural Subtyping

from typing import Protocol, runtime_checkable

@runtime_checkable
class Drawable(Protocol):
    def draw(self) -> str: ...
    def area(self) -> float: ...

class Circle:
    def __init__(self, radius: float):
        self.radius = radius
    def draw(self) -> str:
        return f"Circle(r={self.radius})"
    def area(self) -> float:
        import math
        return math.pi * self.radius ** 2

class Square:
    def __init__(self, side: float):
        self.side = side
    def draw(self) -> str:
        return f"Square(s={self.side})"
    def area(self) -> float:
        return self.side ** 2

# No inheritance needed — structural compatibility!
shapes = [Circle(5), Square(4)]
for shape in shapes:
    print(f"{shape.draw()}: area={shape.area():.2f}")
    print(f"  isinstance(Drawable): {isinstance(shape, Drawable)}")

📸 Verified Output:

💡 @runtime_checkable allows isinstance() checks at runtime. Without it, Protocol is only checked by static type checkers like mypy. Note: runtime checks only verify method existence, not signatures.

Step 2: Protocol with __call__

Step 3: Generic Protocols

Step 4: Covariant and Contravariant TypeVar

Step 5: ParamSpec — Preserving Callable Signatures

Step 6: TypeVarTuple — Variadic Generics

Step 7: overload — Multiple Signatures

Step 8: Capstone — Type-Safe Plugin Framework

📸 Verified Output:

Summary

Concept
API
Use Case

Structural typing

Protocol

Duck typing with type safety

Runtime checks

@runtime_checkable

isinstance with Protocol

Callable protocol

Protocol.__call__

Type-safe higher-order functions

Generic protocol

Protocol[T]

Type-parameterized interfaces

Covariance

TypeVar(covariant=True)

Producer types

Contravariance

TypeVar(contravariant=True)

Consumer types

ParamSpec

P.args, P.kwargs

Decorator signature preservation

overload

Multiple signatures

Type-aware dispatch

Last updated