Skip to content
This repository has been archived by the owner on Jan 25, 2024. It is now read-only.

Use Board.name in BoardGroup.singular error message #342

Open
kierdavis opened this issue Jul 16, 2019 · 2 comments
Open

Use Board.name in BoardGroup.singular error message #342

kierdavis opened this issue Jul 16, 2019 · 2 comments
Labels
refactor typing A incorrect or loose type that needs correcting.
Milestone

Comments

@kierdavis
Copy link
Contributor

It would be nice to use the board's human-readable name, Board.name, in the error message produced by BoardGroup.singular when the wrong number of boards are connected.

The relevant section of code in BoardGroup.singular:

name = self._backend_class.board.__name__
raise CommunicationError(f"expected exactly one {name} to be connected, but found {num}")

I'd like to write this as:

name: str = self._backend_class.board.name
...

However, I get a type error:

j5/boards/board.py:108: error: "Callable[[Backend], Type[Board]]" has no attribute "name"

This is because Backend.board is declared as an instance property rather than a class attribute (in order to get the effect of abstractmethod). This means that although the type of self._backend_class().board is Type[Board], the type of self._backend_class.board is actually Callable[[Backend], Type[Board]], because the property's descriptor hasn't kicked in.

This could be solved at the typechecking level by instead declaring Backend.board as a class attribute:

class Backend:
    board: Type['Board']

but then we lose the effect of abstractmethod: Backends can now be instantiated even if they don't define a board attribute, like so:

class BadBackend(Backend):
    @classmethod
    def discover(cls) -> Set['Board']:
        raise NotImplementedError
    environment = Environment("MockEnvironment")
    # board = Board
    firmware_version = None
BadBackend()  # shouldn't be allowed to succeed

I wonder if we can construct an "abstract attribute" mechanism that ties in with the standard abc mechanisms? Alternatively, maybe we can just convince the typechecker that the attribute is abstract without it having to be enforced at runtime?

@trickeydan
Copy link
Contributor

https://docs.python.org/3/library/typing.html#typing.ClassVar

@kierdavis
Copy link
Contributor Author

It would also be nice to do this in SerialHardwareBackend.read_serial_line.

@trickeydan trickeydan added this to the 1.0.0 milestone Aug 7, 2019
@trickeydan trickeydan modified the milestones: Pre-1.0.0, Post 1.0.0 Aug 7, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
refactor typing A incorrect or loose type that needs correcting.
Projects
None yet
Development

No branches or pull requests

2 participants