adafruit / Adafruit_Blinka

Add CircuitPython hardware API and libraries to MicroPython & CPython devices
https://learn.adafruit.com/circuitpython-on-raspberrypi-linux
MIT License
439 stars 328 forks source link

Project dependencies may have API risk issues #623

Closed PyDeps closed 1 year ago

PyDeps commented 1 year ago

Hi, In Adafruit_Blinka, inappropriate dependency versioning constraints can cause risks.

Below are the dependencies and version constraints that the project is using

Adafruit-PlatformDetect>=3.13.0
Adafruit-PureIO>=1.1.7
Jetson.GPIO;platform_machine=='aarch64'
RPi.GPIO;platform_machine=='armv7l'orplatform_machine=='armv6l'
rpi_ws281x>=4.0.0;platform_machine=='armv7l'orplatform_machine=='armv6l'
sysv_ipc>=1.1.0;sys_platform=='linux'andplatform_machine!='mips'
pyftdi>=0.40.0
binho-host-adapter>=0.1.6
numpy>=1.21.5
adafruit-circuitpython-typing

The version constraint == will introduce the risk of dependency conflicts because the scope of dependencies is too strict. The version constraint No Upper Bound and * will introduce the risk of the missing API Error because the latest version of the dependencies may remove some APIs.

After further analysis, in this project, The version constraint of dependency Adafruit-PureIO can be changed to >=1.1.0,<=1.1.9. The version constraint of dependency pyftdi can be changed to >=0.30.0,<=0.54.0.

The above modification suggestions can reduce the dependency conflicts as much as possible, and introduce the latest version as much as possible without calling Error in the projects.

The invocation of the current project includes all the following methods.

The calling methods from the Adafruit-PureIO
Adafruit_PureIO.spi.SPI
The calling methods from the pyftdi
pyftdi.i2c.I2cController.get_gpio
pyftdi.i2c.I2cController
pyftdi.spi.SpiController
pyftdi.i2c.I2cController.configure
The calling methods from the all methods
testing.board.i2c.I2C
mcp2221.mcp2221.gpio_set_pin
self._spi.get_gpio
Direction
os.lseek
self._digitalinouts.append
self._scan_thread.join
binhoHostAdapter.binhoHostAdapter.binhoHostAdapter
self._hid.write
hash
setuptools.setup
utime.ticks_diff
self._nova.setClockSPI
self._pin.set_state
RPi.GPIO.setmode
pkg_resources.get_distribution.str.split
Jetson.GPIO.cleanup
self._mcp2221._i2c_configure
rp2040_u2if.rp2040_u2if.i2c_readfrom_into
test_module
self._write_pin_attr
rp2040_u2if.rp2040_u2if.pwm_deinit
self._nova.readBytesI2C.split
filter
pathlib.Path
disable
self.get_last_received_report
f_label.read.strip
scanResults.append
self.pwm_deinit
len.to_bytes
lineOutput.split
self._mq.send
self._nova.getCommandVer.split
adafruit_blinka.agnostic.time.sleep
self._nova.scanAddrI2C
self._i2c_bus.read_byte
adafruit_blinka.microcontroller.ftdi_mpsse.mpsse.url.get_ft232h_url
_struct_time
self._mq.remove
self.report_ids.report_id.this.gadget_root.Path.read_text.strip.split
self._pin.get_state
self._pwmpin.stop
unittest.TestRunner
self._uart.deinit
rp2040_u2if.rp2040_u2if.i2c_writeto_then_readfrom
self._gf.pattern_generator.stop
i2c.writeto_then_readfrom
machine.Pin
self._nova.setNumericalBase
Pin.mpsse_gpio.set_direction
subprocess.Popen
float
adafruit_blinka.microcontroller.nova.Connection.getInstance
self._uart.readline
gc.collect
self._line.set_value
_rpi_ws281x.ws2811_channel_get
adafruit_blinka.microcontroller.generic_micropython.i2c.I2C
self._nova.getCommandVer
microcontroller.pin.Pin._nova.getIOpinValue
rp2040_u2if.rp2040_u2if.pwm_set_frequency
MCP2221
Jetson.GPIO.setup
self._i2c_bus.read_bytes
Pin
self._wait_receive_msg
analog_in.read
binhoHostAdapter.binhoUtilities.listAvailableDevices
self._gf.pattern_generator.set_sample_rate
fun
memoryview
rp2040_u2if.rp2040_u2if.i2c_scan
self.set_no_cs
temp_c
this.gadget_root.Path.glob
self._uart.read
mcp2221.mcp2221.adc_read
machine.UART
min
Adafruit_BBIO.GPIO.setup
DriveMode
threading.RLock
self._nova.writeBridgeUART
hid.enumerate
unittest.TestSuite
queues.remove
self._nova.clearBuffer
self._i2c.poll
range
int
_rpi_ws281x.ws2811_led_set
gpiod.Chip.num_lines
Device
Jetson.GPIO.input
self._nova.setStopBitsUART
adafruit_platformdetect.Detector
busio.SPI.unlock
str.append
self.readfrom_into
f_unexport.write
f.read
adafruit_blinka.microcontroller.generic_linux.libgpiod_pin.Pin
RPi.GPIO.input
this.gadget_root.Path.rglob
self._spi.get_port
self._line.write
struct.calcsize
self._nova.setModeSPI
self._nova.transferBufferSPI
self.init
digitalio.DigitalInOut.switch_to_input
fd.write
pathlib.Path.read_text.find
self._nova.beginSPI
self._i2c.writeto
Parity
self._scan_thread.is_alive
I2C
self._chip_path.format
absolute.split
self.writeto
int.from_bytes
self._hid.open_path
f_direction.write
proc.terminate
adafruit_bno055.BNO055
property.strip
mcp2221.mcp2221.dac_configure
self._i2c.get_gpio
self.assertTrue
self._read_channel_attr
self._spi.readinto
_rpi_ws281x.delete_ws2811_t
busio.I2C
self._i2c.scan
self._i2c_status
queues.append
int.lower
Jetson.GPIO.setmode
self.read
self._events.keypad_eventqueue_record
adafruit_gps.GPS.update
Event
self._device_path.format
PWMOut._nova.setOperationMode
GPIOError
self._mcp2221.i2c_writeto
Pin._nova.getIOpinValue
pathlib.Path.glob
self._gf.pattern_generator.scan_out_pattern
self._row_digitalinouts.append
pyftdi.i2c.I2cController.get_gpio
function_root.Path.write_text
self._line.request
config_dir.is_dir
self.i2c_writeto
_rpi_ws281x.ws2811_channel_t_strip_type_get
self._pwmpin.ChangeFrequency
RPi.GPIO.PWM
self._pin_path.format
self._gf.i2c.write
os.close
self._i2c_read
found.append
greatfet.GreatFET
self._nova.getClockSPI
os.write
Jetson.GPIO.setwarnings
self._mcp2221.i2c_writeto_then_readfrom
self._hid.open
RuntimeError
tuple
rp2040_u2if.rp2040_u2if.gpio_set_pin
self._nova.writeToReadFromSPI
type
yes_no
os.path.abspath
self._nova.setPullUpStateI2C
self._nova.setBaudRateUART
ucollections.namedtuple
dir
rp2040_u2if.rp2040_u2if.adc_get_value
self._nova.setEscapeSequenceUART
rp2040_u2if.rp2040_u2if.pwm_get_frequency
rp2040_u2if.rp2040_u2if.neopixel_write
adafruit_gps.GPS.send_command
os.path.join
adafruit_blinka.patch_system
rp2040_u2if.rp2040_u2if.i2c_set_port
busio.SPI.write
self._chip.get_line
f_label.read
self._serial.reset_output_buffer
get_dts_alias
self._spi.write
microcontroller.pin.Pin._nova.setIOpinValue
mcp2221.mcp2221.dac_write
bytearray.extend
self._pin.read_samples
self.report_ids.report_id.this.gadget_root.Path.read_text
collections.deque
baudrate.to_bytes
self._lock.acquire
rp2040_u2if.rp2040_u2if.spi_configure
self._nova.setDataBitsUART
buf.append
adafruit_blinka.microcontroller.ftdi_mpsse.mpsse.url.get_ft2232h_url
threading.Thread
TimeoutError
self._row_column_to_key_number
_rpi_ws281x.ws2811_render
self._nova.writeToBuffer
busio.SPI.configure
adafruit_bme280.Adafruit_BME280_I2C
self._nova.setOperationMode
self._is_deinited
io.open
utime.ticks_ms
PWMError
self._nova.writeToReadFromI2C
report_id.config_root.Path.symlink_to
self._read_pin_attr
f_export.write
os.path.exists
frequency.to_bytes
self._nova.writeToReadFromSPI.split
open
self._i2c_state
Adafruit_PureIO.smbus.SMBus
Adafruit_BBIO.GPIO.output
self._hid_xfer
self._i2c.writeto_then_readfrom
self.id.Pin._nova.getIOpinValue.split
this.gadget_root.Path.rmdir
adafruit_blinka.microcontroller.mcp2221.pin.Pin
PWMOut._nova.getIOpinPWMFreq
RPi.GPIO.setwarnings
self.report_ids.report_id.this.gadget_root.Path.read_text.strip
busio.I2C.readfrom_into
os.open
config_root.Path.mkdir
this.devices.append
function_dir.is_dir
_rpi_ws281x.ws2811_channel_t_invert_set
self.pwm_set_duty_cycle
mcp2221.mcp2221.gpio_set_direction
self._clock.deinit
TypeError
gpiod.Chip.close
self.assertIsNotNone
os.path.dirname
adafruit_gps.GPS
self._serial.flush
ord
mcp2221.mcp2221.gp_set_mode
random.randint
ImportError
buffer.append
self._set_enabled
next
self._events.popleft
rp2040_u2if.rp2040_u2if.i2c_writeto
Pull
_rpi_ws281x.ws2811_t_freq_set
Pin.mpsse_gpio.read
sphinx_rtd_theme.get_html_theme_path
self._get_period_ns
function_root.Path.write_bytes
format
pathlib.Path.read_text
isinstance
dio.switch_to_output
self._pretty_report
self._pwmpin.ChangeDutyCycle
analog_out.write
property.lower
super.deinit
digitalio.DigitalInOut.deinit
self._port.set_frequency
self._i2c_bus.read_i2c_block_data
hex
Exception
self._nova.setClockI2C
PWMOut._nova.close
adafruit_blinka.microcontroller.bcm283x.pin.Pin
self._wait_receive_msg.decode
serial.Serial
IndexError
fd.read.split
str
sys.exit
enumerate
greatfet.interfaces.adc.ADC
adafruit_blinka.agnostic.sleep
mcp2221.mcp2221.adc_configure
print
self._nova.setParityUART
self._port.exchange
self._i2c.configure
self._line.release
self.assertIsNone
adafruit_blinka.microcontroller.generic_linux.sysfs_pin.Pin
globals
platform.system
greatfet.interfaces.uart.UART
self.close
self._i2c_cancel
round
self._nova.getClockSPI.split
i2c_devices.append
f_attr.write
self._i2c.get_port
busio.SPI
strings_file.is_dir
self._find_closest_preset
os.set_blocking
match.group.upper
rp2040_u2if.rp2040_u2if.adc_init_pin
pyftdi.spi.SpiController
self.assertEqual
os.path.realpath
test_interactive
RPi.GPIO.cleanup
rp2040_u2if.rp2040_u2if.spi_readinto
adafruit_blinka.microcontroller.ftdi_mpsse.mpsse.pin.Pin
os.environ.get
self.Cls.iteritems
busio.I2C.writeto
function_root.Path.mkdir
self._data.deinit
pyftdi.i2c.I2cController
self._nova.startI2C
self._i2c.get_port.write
list
self.write_readinto
RP2040_u2if
self._scan_thread.start
ValueError
self.get_device_path
fd.fileno
self._nova.readBridgeUART
PWMOut._nova.setIOpinMode
self._hid.read
AttributeError
self._open
gpiod.chip
self._line.read
hid.device
self._get_period
periphery.GPIO
strings_file.rmdir
dio.switch_to_input
sysv_ipc.MessageQueue
getattr
self._channel.format.encode
bytearray
_rpi_ws281x.ws2811_channel_t_gpionum_set
self._port.write
self.deinit
self.pwm_set_frequency
test_module_name
gpiod.Chip
bytes
Pin._nova.setIOpinMode
adafruit_mma8451.MMA8451
self._i2c.get_port.read
self._set_frequency
time.monotonic
adafruit_blinka.microcontroller.generic_linux.periphery_pin.Pin
function_dir.rmdir
OSError
rp2040_u2if.rp2040_u2if.i2c_configure
symlink.unlink
Adafruit_PureIO.spi.SPI
Pin._nova.setIOpinValue
super
rp2040_u2if.rp2040_u2if.pwm_set_duty_cycle
self._pin.set_value
re.search.group
self.get_received_data
RPi.GPIO.output
tuple.append
adafruit_blinka.agnostic.time.monotonic
self._spi.write_readinto
self._write
os.read
MCP2221I2C
hasattr
adafruit_blinka.microcontroller.rp2040_u2if.neopixel.neopixel_write
self._set_duty_cycle
_marshal_time
PWMOut._nova.setIOpinPWMFreq
self._transmit
math.sqrt
__import__
unittest.TestSuite.addTest
self._get_frequency
machine.I2C
NotImplementedError
gf.gpio.get_pin
self._events.clear
self._latch.deinit
self._spi.writebytes
self._reset
self._nova.readBytesI2C
self.id.format.encode
casetype
self._spi.clock_data
LookupError
self._events.append
self.readinto
generic_micropython.Pin
f_attr.read.strip
rp2040_u2if.rp2040_u2if.spi_write_readinto
_rpi_ws281x.ws2811_channel_t_strip_type_set
Cls
self._uart.write
i2c_devices.index
self._mcp2221.i2c_readfrom_into
self._presets.items
rp2040_u2if.rp2040_u2if.gpio_get_pin
self._uart.readinto
serial.tools.list_ports.comports
_EventQueue
self._spi.init
self._pwmpin.PWMOut._nova.getIOpinPWMFreq.split
_rpi_ws281x.new_ws2811_t
atexit.register
rp2040_u2if.rp2040_u2if.open
self._line.get_value
machine.SPI
self._nova.close
f_attr.read
os.path.isdir
analog_in.read.strip
time.sleep
get_voltage
setuptools.find_packages
self.gp_set_mode
Pin.mpsse_gpio.write
config_root.Path.write_text
self._scanning_function
self._spi.set_clock_polarity_and_phase
self._pin.init
busio.SPI.try_lock
self._nova.beginBridgeUART
repr
self._nova.setIOpinMode
this.gadget_root.Path.write_text
self._process.terminate
self._line.close
self._pin.initialize
f_direction.read
self._close
re.search
unittest.TestRunner.run
output.format
adafruit_blinka.microcontroller.rp2040_u2if.pin.Pin
self._nova.stopBridgeUART
divmod
analogio.AnalogIn
self._write_channel_attr
config_dir.rmdir
property
SyntaxError
testing.await_true
input
rp2040_u2if.rp2040_u2if.spi_write
self._i2c_bus.write_bytes
bytearray.append
pyftdi.i2c.I2cController.configure
abs
self._set_period
digitalio.DigitalInOut
adafruit_blinka.microcontroller.nxp_lpc4330.pin.Pin
self._spi.transfer
len
adafruit_blinka.microcontroller.generic_micropython.spi.SPI
this.gadget_root.Path.mkdir
self._hid.close
_rpi_ws281x.ws2811_fini
self._i2c.readfrom_into
self._gf.i2c.read
self._pwmpin.start
rp2040_u2if.rp2040_u2if.pwm_get_duty_cycle
report_id.to_bytes
_rpi_ws281x.ws2811_init
mcp2221.mcp2221.gpio_get_pin
self.gpio_set_direction
self._pin.value
self._nova.writeByteI2C
casetype.setUp
rp2040_u2if.rp2040_u2if.pwm_configure
busio.I2C.scan
_rpi_ws281x.ws2811_t_dmanum_set
self._nova.endI2C
self._spi.configure
rp2040_u2if.rp2040_u2if.gpio_init_pin
self._mq.receive
self._channel_path.format
Adafruit_BBIO.GPIO.input
procs.remove
procs.append
duty_cycle.to_bytes
testing.yes_no
DigitalInOut
self._nova.transferSPI
self._read
os.readlink
issubclass
rp2040_u2if.rp2040_u2if.spi_set_port
busio.UART
RPi.GPIO.setup
q.remove
Connection
self._mcp2221.i2c_scan
sys.path.insert
Jetson.GPIO.output
self._gf.i2c.scan
_rpi_ws281x.ws2811_channel_t_brightness_set
digitalio.DigitalInOut.switch_to_output
self._i2c.get_port.exchange
super.__init__
self._column_digitalinouts.append
_rpi_ws281x.ws2811_channel_t_gpionum_get
adafruit_blinka.microcontroller.rp2040_u2if.pin.GP0._u2if_open_hid
locals
fd.read
os.readlink.split
_rpi_ws281x.ws2811_channel_t_count_set
pkg_resources.get_distribution
self._mcp2221.i2c_configure
neopixel_cleanup
self._i2c_write
_rpi_ws281x.ws2811_get_return_t_str
gpiod.line_request
self._lock.release
self._pin.set_direction
os.environ.get.startswith
self._serial.write

@developer Could please help me check this issue? May I pull a request to fix it? Thank you very much.

makermelissa commented 1 year ago

Hmm, yeah. I can see some potential issues, such as when trying to install on Raspberry Pi 64-bit (aarch64), it would attempt to install Jetson.GPIO, but not RPi.GPIO with how it is now. The == only refers to requiring it for that platform.

In regards to the requested changes, keep in mind this project runs in many environments, which makes changes like these super tricky to make without breaking things:

  1. It needs to run on MicroPython for a few boards and changing this file shouldn't affect it.
  2. It needs to run on a variety of different processors with different dependencies.
  3. It needs to run in a number of linux distros with different package requirements.
  4. For other boards, it runs on Windows/Linux/Mac and communicates with a connected board like the FT232H and MCP2222.
  5. It needs to be able to run in the CI environment and pass checks.

In most installations, the setup.py file is what is executed rather than the requirements file and it's even more complex. The CI environment definitely uses the requirements.txt though.

For items such as Adafruit-PureIO, we wouldn't want to have users with versions before 1.1.7 because of bugs, which can cause support issues. Also, there's no need to put an upper bounds on that since it's primarily used by Blinka and I maintain both it and Blinka, so I'm well aware if any APIs are updated.

As for pyftdi, we could add an upper bound, but this will likely end up being more maintenance overhead keeping up on new version changes than it would fixing it on the off chance that some api is removed and also more likely cause dependency version constraints as you mentioned if they aren't kept up.

Now with that being said, are there particular version constraints that you are running into? If not, is there another reason that would justify the additional maintenance overhead?