Files
example-code-2e/15-more-types/cafeteria.py
2021-05-21 00:26:43 -03:00

83 lines
1.9 KiB
Python

from typing import TypeVar, Generic
class Beverage:
"""Any beverage"""
class Juice(Beverage):
"""Any fruit juice"""
class OrangeJuice(Juice):
"""Delicious juice from Brazilian oranges"""
BeverageT = TypeVar('BeverageT', covariant=True)
class BeverageDispenser(Generic[BeverageT]):
def __init__(self, beverage: BeverageT) -> None:
self.beverage = beverage
def dispense(self) -> BeverageT:
return self.beverage
class Garbage:
"""Any garbage."""
class Biodegradable(Garbage):
"""Biodegradable garbage."""
class Compostable(Biodegradable):
"""Compostable garbage."""
GarbageT = TypeVar('GarbageT', contravariant=True)
class TrashCan(Generic[GarbageT]):
def put(self, trash) -> None:
"""Store trash until dumped..."""
class Cafeteria:
def __init__(
self,
dispenser: BeverageDispenser[Juice],
trash_can: TrashCan[Biodegradable]
):
"""Initialize..."""
beverage_dispenser = BeverageDispenser(Beverage())
juice_dispenser = BeverageDispenser(Juice())
orange_juice_dispenser = BeverageDispenser(OrangeJuice())
trash_can: TrashCan[Garbage] = TrashCan()
bio_can: TrashCan[Biodegradable] = TrashCan()
compost_can: TrashCan[Compostable] = TrashCan()
arnold_hall = Cafeteria(juice_dispenser, bio_can)
######################## covariance on 1st argument
arnold_hall = Cafeteria(orange_juice_dispenser, trash_can)
## Argument 1 to "Cafeteria" has
## incompatible type "BeverageDispenser[Beverage]"
## expected "BeverageDispenser[Juice]"
# arnold_hall = Cafeteria(beverage_dispenser, trash_can)
######################## contravariance on 2nd argument
## Argument 2 to "Cafeteria" has
## incompatible type "TrashCan[Compostable]"
## expected "TrashCan[Biodegradable]"
# arnold_hall = Cafeteria(juice_dispenser, compost_can)
arnold_hall = Cafeteria(juice_dispenser, trash_can)