RosettaCodeData/Task/Constrained-genericity/Python/constrained-genericity.py

43 lines
911 B
Python

"""Constrained genericity. Requires Python >= 3.9."""
from typing import Generic
from typing import Protocol
from typing import TypeVar
from typing import runtime_checkable
T = TypeVar("T", covariant=True)
@runtime_checkable
class Edible(Protocol[T]):
def eat(self) -> T: ...
class FoodBox(Generic[T]):
def __init__(self, *food: Edible[T]):
# Runtime type checking
for item in food:
if not isinstance(item, Edible):
raise TypeError(f"expected food, found {item.__class__.__name__}")
self.contents = food
class Cheese:
def eat(self) -> None:
print("eating cheese")
class Shoe:
def wear(self) -> None:
print("wearing shoe")
if __name__ == "__main__":
box = FoodBox[None](Cheese())
for food in box.contents:
food.eat()
# This fails static type checking.
box = FoodBox[None](Cheese(), Shoe())