-
Notifications
You must be signed in to change notification settings - Fork 12
Description
Python nowadays supports "protocols". Protocols are mostly a typing thing, and allow you to specify that a class follows the protocol without explicitly being a subclass.
When using the BMI as an abstract base class, you currently need to use the following syntax:
def update_bmi(bmi: BmiABC) -> None:
bmi.update()
class BmiImplementation(BmiABC):
def update(self) -> None:
....
update_bmi(BmiImplementation()) # happy type checker
If you don't subclass BMI, type checkers will get angry at this, as BmiImplementation
is not a subclass of BmiABC
:
def update_bmi(bmi: BmiABC) -> None:
bmi.update()
class BmiImplementation:
def update(self) -> None:
....
update_bmi(BmiImplementation()) # sad type checker
However, if you specify that Bmi
is a subclass of typing.protocol
, the following syntax passes type checkers:
def update_bmi(bmi: BmiProtocol) -> None:
bmi.update()
class BmiImplementation:
def update(self) -> None:
...
update_bmi(BmiImplementation()) # happy type checker
This is because type checkers will check if BmiImplementation
follows the BmiProtocol
: does it have all methods that are in the protocol, and do all the methods have the correct typing.
To implement this, all that we would need to change is;
from typing import Protocol
class Bmi(Protocol):
Note that you can still subclass from Protocol like you could from an ABC.