Skip to content

Avoid SPIDevice init failure in absence of libgpiod bindings #102

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

ilario
Copy link

@ilario ilario commented Jan 14, 2025

When importing other Adafruit components, I observed this error:

[...]
    from adafruit_register.i2c_struct import ROUnaryStruct, UnaryStruct
  File "/opt/measurement_system-venv/lib/python3.9/site-packages/adafruit_register/i2c_struct.py", line 22, in <module>
    from circuitpython_typing.device_drivers import I2CDeviceDriver
  File "/opt/measurement_system-venv/lib/python3.9/site-packages/circuitpython_typing/device_drivers.py", line 13, in <module>
    from adafruit_bus_device.spi_device import SPIDevice
  File "/opt/measurement_system-venv/lib/python3.9/site-packages/adafruit_bus_device/spi_device.py", line 29, in <module>
    class SPIDevice:
  File "/opt/measurement_system-venv/lib/python3.9/site-packages/adafruit_bus_device/spi_device.py", line 76, in SPIDevice
    chip_select: Optional[DigitalInOut] = None,
NameError: name 'DigitalInOut' is not defined

This is happening because I did not have the "libgpiod Python bindings" (installable with pip install gpiod) and the import here fails:

from digitalio import DigitalInOut

Causing this line to fail:

chip_select: Optional[DigitalInOut] = None,

This started happening with adafruit/Adafruit_CircuitPython_Typing#42 as it introduced importing adafruit_bus_device.spi_device.SPIDevice.

@tekktrik
Copy link
Member

It sounds like this happened while using Blinka, but Blinka should have definitions for DigitalInOut I thought. Can you help me understand how you either don't have gpiod installed when you installed Blinka, or what your setup is so I can understand if something happened on the Blinka side of things?

@tekktrik tekktrik self-requested a review June 11, 2025 22:19
@ilario
Copy link
Author

ilario commented Jun 12, 2025

Can you help me understand how you either don't have gpiod installed when you installed Blinka, or what your setup is so I can understand if something happened on the Blinka side of things?

In am on a A64-OLinuXino by Olimex. From what I can trace back, I installed Blinka using
pip install Adafruit-Blinka and that did not install gpiod as a dependency.

I have no idea if it should be a dependency (maybe it is not a dependency so that you can use libgpiod-dev from the system. Or because micropython stuff does not need it?), but if you add it as a dependency you should remove also these warnings:
https://github.com/adafruit/Adafruit_Blinka/blob/5b07bb9fc2fda92e5fc85c83b37ad7864bd5fd72/src/adafruit_blinka/microcontroller/generic_linux/libgpiod_pin.py#L5-L11

It sounds like this happened while using Blinka, but Blinka should have definitions for DigitalInOut I thought.

It is defined there indeed, but it fails when importing in absence of gpiod.

The traceback is more or less the following:
https://github.com/adafruit/Adafruit_Blinka/blob/8f45d6cbc540dd809d753fc3af599b63afddf615/src/digitalio.py#L77

https://github.com/adafruit/Adafruit_Blinka/blob/8f45d6cbc540dd809d753fc3af599b63afddf615/src/adafruit_blinka/microcontroller/allwinner/a64/pin.py#L5

https://github.com/adafruit/Adafruit_Blinka/blob/5b07bb9fc2fda92e5fc85c83b37ad7864bd5fd72/src/adafruit_blinka/microcontroller/generic_linux/libgpiod_pin.py#L6

So, I think that either we do as proposed in this pull request or we take from digitalio import DigitalInOut out o the try block.

@FoamyGuy
Copy link
Contributor

I'm not familiar with A64-OLinuXino device, but it sounds to me perhaps it has different requirements for using GPIO pins compared to RPi. I don't think it's an issue with Blinka, but I've really only messed with RPi hardware, not ventured out to the others.

If the rest of the code works on that device and only the import for typing is preventing it from working, then I think it's fine to have this workaround to avoid the import / typing error.

@ilario
Copy link
Author

ilario commented Jun 13, 2025

Sorry, maybe I gave the impression that this was an A64-OLinuXino specific issue. It is not. The issue was a very minor one and does not deserve more discussion, IMHO.
If you want me to discuss more on this, please let me know :)
Thanks for approving.

@tekktrik
Copy link
Member

The issue I'm concerned about is that using this library should inherently require the use of Adafruit Blinka, which needs to (and already should) provide the necessary definition for digitalio.DigitalInOut, so it's not so much that this issue is specific to your board as to the fact that I'm confused how it is that digitalio.DigitalInOut isn't defined at all. I guess I'm wondering if this board is supported by Blinka, which I'm not sure it is, which would explain why it isn't defined.

@tekktrik
Copy link
Member

tekktrik commented Jun 13, 2025

And if it is supported (perhaps by the A64 definition), then the question is should Blinka raise an issue if gpiod is not installed when it's expected, or that digitalio.DigitalInOut cannot be created for the current board. It is worth noting that I don't see a board definition.

@ilario
Copy link
Author

ilario commented Jun 14, 2025

The issue I'm concerned about is that using this library should inherently require the use of Adafruit Blinka, which needs to (and already should) provide the necessary definition for digitalio.DigitalInOut

You are right, it does.

so it's not so much that this issue is specific to your board

Exactly, the issue is not board-specific.

as to the fact that I'm confused how it is that digitalio.DigitalInOut isn't defined at all.

It is defined, but it fails when importing if gpiod is missing. Then this try-except block catches the ImportError:

try:
from typing import Optional, Type
from types import TracebackType
# Used only for type annotations.
from busio import SPI
from digitalio import DigitalInOut
except ImportError:
pass

And if it is supported (perhaps by the A64 definition), then the question is should Blinka raise an issue if gpiod is not installed when it's expected

It does:
https://github.com/adafruit/Adafruit_Blinka/blob/5b07bb9fc2fda92e5fc85c83b37ad7864bd5fd72/src/adafruit_blinka/microcontroller/generic_linux/libgpiod_pin.py#L5-L11
but the aforementioned try-except block catches it again.

So, either:

  • we take that from digitalio import DigitalInOut import out of the try-except block
  • or we do as proposed in this pull request, which is to define it to a None value just for avoiding the typing error when the import fails for whatever reason

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants