Skip to content

Change from ABC to protocol. #58

@BSchilperoort

Description

@BSchilperoort

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions