Adafruit CircuitPython Typing
adafruit-circuitpython-typing provides Python type hints, specifically Protocol definitions and TypeAliases, for common hardware interface types found in CircuitPython, such as BlockDevice, SPIDevice, and AnyDisplay. It facilitates static type checking for CircuitPython applications developed in CPython environments. The library is currently at version 1.12.3 and is actively maintained with frequent minor releases.
Common errors
-
ModuleNotFoundError: No module named 'adafruit_circuitpython_typing'
cause The `adafruit-circuitpython-typing` library has not been installed in your current Python environment.fixRun `pip install adafruit-circuitpython-typing` to install the package. -
TypeError: 'BlockDevice' is not a type object
cause You are attempting to instantiate a Protocol or TypeAlias (e.g., `my_device = BlockDevice()`) instead of using it as a type hint.fixProtocols and TypeAliases are for type checking, not for creating objects. Use them in type annotations like `my_function(device: BlockDevice)`. -
SyntaxError: '/' is an invalid character in identifier
cause This error can occur if you are running `adafruit-circuitpython-typing` (version 1.10.3 or higher) on a Python version older than 3.8, which does not support position-only arguments used within the library's internal type definitions.fixUpgrade your Python environment to Python 3.8 or newer. The library explicitly requires `python_requires='>=3.8'`.
Warnings
- gotcha This library primarily provides `Protocol` definitions and `TypeAlias` types for static analysis. You should not attempt to instantiate `BlockDevice()`, `SPIDevice()`, or similar types at runtime, as they are not designed for that and will raise a `TypeError`.
- breaking As of version 1.10.3, `adafruit-circuitpython-typing` requires Python 3.8 or newer. Using it with older Python versions will result in installation failures or `SyntaxError` due to features like position-only arguments used internally.
- gotcha This library is designed for CPython development environments to provide type hints for CircuitPython code. It is NOT intended to be installed or run directly on microcontrollers or used to build .mpy bundles, as it contains syntax incompatible with `mpy-cross` and microcontroller targets.
Install
-
pip install adafruit-circuitpython-typing
Imports
- BlockDevice
from adafruit_circuitpython_typing import BlockDevice
- AnyDisplay
from adafruit_circuitpython_typing import AnyDisplay
- SPIDevice
from adafruit_circuitpython_typing import SPIDevice
Quickstart
from adafruit_circuitpython_typing import BlockDevice, AnyDisplay
from typing import Protocol
# Define a mock BlockDevice for demonstration purposes
class MockBlockDevice(Protocol):
def readblocks(self, start_block: int, buf: bytearray) -> None:
print(f"Reading block {start_block}")
def writeblocks(self, start_block: int, buf: bytearray) -> None:
print(f"Writing block {start_block}")
def ioctl(self, operation: int, arg: int) -> int:
print(f"IOCTL operation {operation} with arg {arg}")
return 0
# A function that expects any BlockDevice
def format_device(device: BlockDevice) -> None:
print(f"Formatting a device of type: {type(device).__name__}")
device.writeblocks(0, bytearray(512))
# A function that expects any display type
def initialize_display(display: AnyDisplay) -> None:
print(f"Initializing display of type: {type(display).__name__}")
# In a real scenario, this would call display methods like show(), fill(), etc.
# Example usage:
my_sd_card = MockBlockDevice()
format_device(my_sd_card)
# A mock display object (in reality, it would be from a CircuitPython display driver)
class MockDisplay:
def show(self) -> None: pass
def fill(self, color: int) -> None: pass
my_oled_display = MockDisplay()
initialize_display(my_oled_display)
print("Type hints used successfully for static analysis.")