Skip to content

digitalio.DigitalInOutProtocol is absent #36

Description

@begeistert

digitalio-stubs declares a typing.Protocol:

class DigitalInOutProtocol(Protocol):
    """Protocol for digital input/output pin control.

    Any object that implements this protocol can be used as a digital pin,
    providing compatibility with code expecting a `digitalio.DigitalInOut`.
    """
    def deinit(self) -> None: ...
    def deinited(self) -> bool: ...
    ...

It exists upstream so a library can accept "anything digitalio.DigitalInOut-shaped" (an I/O
expander pin, say) without importing the concrete class. The layer has no Protocol type at
all, and it is worth checking first whether PyMCU's compiler accepts typing.Protocol as a
base class before adding one here: structural typing has no run-time representation to check
against on a target with no isinstance machinery for it, so this may need compiler support,
or a decision that it type-checks under CPython only and is erased at compile time.

Found while building the CircuitPython API parity suite (tests/parity/) against
circuitpython-stubs 10.3.1: PyMCU/pymcu-circuitpython, tests/parity/allowlist.toml,
symbol digitalio.DigitalInOutProtocol.


2026-09-15: confirmed, this needs compiler support

Measured directly: from typing import Protocol alone is refused before the class body is
even reached --

error: ImportError: Module not found: typing -- 'typing' is a Python standard module, not a
PyMCU library, so `pymcu install` has nothing to fetch. PyMCU reads annotations straight
from the source, so nothing needs importing; the width names live in pymcu.types.

So this is not a matter of Protocol specifically refusing as a base class; the typing
module is not importable at all, under any stdlib flavor. There is no TYPE_CHECKING-style
guard available either, since guarding an import behind it needs the same typing import
this one already fails on. Defining DigitalInOutProtocol here needs the compiler to accept
some import from typing (even a no-op one under if TYPE_CHECKING:), which is language
work, not something this layer can route around on its own. Left tracked.

Filed as PyMCU/PyMCU#444 (milestone Types): extend the no-op handling #417 gave the guarded
try/TYPE_CHECKING forms to a bare, unguarded from typing import X.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions