Skip to content

Importing versions >=1.10.3 broken in CPython #93

Closed
@kevincon

Description

@kevincon

Some of the imports introduced in #87 (released in version 1.10.3) appear to break the import of adafruit_requests in CPython due to those new imports not being part of the adafruit_requests package's requirements.

To reproduce, you can create a fresh virtual environment and install adafruit-circuitpython-requests==1.10.4:

kevin@penguin:~$ python3 -m venv repro_venv
kevin@penguin:~$ . ./repro_venv/bin/activate
(repro_venv) kevin@penguin:~$ pip install adafruit-circuitpython-requests==1.10.4
Collecting adafruit-circuitpython-requests==1.10.4
  Downloading adafruit-circuitpython-requests-1.10.4.tar.gz (39 kB)
Collecting Adafruit-Blinka
  Downloading Adafruit-Blinka-6.17.0.tar.gz (153 kB)
     |████████████████████████████████| 153 kB 2.8 MB/s 
Collecting Adafruit-PlatformDetect>=3.13.0
  Downloading Adafruit-PlatformDetect-3.18.0.tar.gz (31 kB)
Collecting Adafruit-PureIO>=1.1.7
  Downloading Adafruit_PureIO-1.1.9.tar.gz (26 kB)
Collecting pyftdi>=0.40.0
  Downloading pyftdi-0.53.3-py3-none-any.whl (141 kB)
     |████████████████████████████████| 141 kB 13.6 MB/s 
Collecting pyserial>=3.0
  Downloading pyserial-3.5-py2.py3-none-any.whl (90 kB)
     |████████████████████████████████| 90 kB 3.1 MB/s 
Collecting pyusb!=1.2.0,>=1.0.0
  Downloading pyusb-1.2.1-py3-none-any.whl (58 kB)
     |████████████████████████████████| 58 kB 1.5 MB/s 
Using legacy 'setup.py install' for adafruit-circuitpython-requests, since package 'wheel' is not installed.
Using legacy 'setup.py install' for Adafruit-Blinka, since package 'wheel' is not installed.
Using legacy 'setup.py install' for Adafruit-PlatformDetect, since package 'wheel' is not installed.
Using legacy 'setup.py install' for Adafruit-PureIO, since package 'wheel' is not installed.
Installing collected packages: pyusb, pyserial, pyftdi, Adafruit-PureIO, Adafruit-PlatformDetect, Adafruit-Blinka, adafruit-circuitpython-requests
    Running setup.py install for Adafruit-PureIO ... done
    Running setup.py install for Adafruit-PlatformDetect ... done
    Running setup.py install for Adafruit-Blinka ... done
    Running setup.py install for adafruit-circuitpython-requests ... done
Successfully installed Adafruit-Blinka-6.17.0 Adafruit-PlatformDetect-3.18.0 Adafruit-PureIO-1.1.9 adafruit-circuitpython-requests-1.10.4 pyftdi-0.53.3 pyserial-3.5 pyusb-1.2.1

And then try importing adafruit_requests in the interpreter:

(repro_venv) kevin@penguin:~$ python
Python 3.9.2 (default, Feb 28 2021, 17:03:44) 
[GCC 10.2.1 20210110] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import adafruit_requests
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/kevin/repro_venv/lib/python3.9/site-packages/adafruit_requests.py", line 107, in <module>
    class Response:
  File "/home/kevin/repro_venv/lib/python3.9/site-packages/adafruit_requests.py", line 114, in Response
    def __init__(self, sock: SocketType, session: Optional["Session"] = None) -> None:
NameError: name 'SocketType' is not defined

I believe one of the imports of adafruit_esp32spi, adafruit_wiznet5k, etc. in this try block fail with ImportError since they are not requirements of adafruit-circuitpython-requests and thus don't get installed by pip, so the SocketType type var does not get defined (hence the error above):

try:
from typing import Union, TypeVar, Optional, Dict, Any, List, Type
import types
from types import TracebackType
import ssl
import adafruit_esp32spi.adafruit_esp32spi_socket as esp32_socket
import adafruit_wiznet5k.adafruit_wiznet5k_socket as wiznet_socket
import adafruit_fona.adafruit_fona_socket as cellular_socket
from adafruit_esp32spi.adafruit_esp32spi import ESP_SPIcontrol
from adafruit_wiznet5k.adafruit_wiznet5k import WIZNET5K
from adafruit_fona.adafruit_fona import FONA
import socket as cpython_socket
SocketType = TypeVar(
"SocketType",
esp32_socket.socket,
wiznet_socket.socket,
cellular_socket.socket,
cpython_socket.socket,
)
SocketpoolModuleType = types.ModuleType
SSLContextType = (
ssl.SSLContext
) # Can use either CircuitPython or CPython ssl module
InterfaceType = TypeVar("InterfaceType", ESP_SPIcontrol, WIZNET5K, FONA)
except ImportError:
pass

but since the try block's exception handler passes on ImportError, we don't see an error until the first attempted usage of SocketType in this type annotation:

def __init__(self, sock: SocketType, session: Optional["Session"] = None) -> None:

I read on Discord someone else ran into this as well: https://discord.com/channels/327254708534116352/537365702651150357/925282376525959229

Since those adafruit_esp32spi, adafruit_wiznet5k, etc. packages don't seem to be used beyond defining the SocketType, InterfaceType, etc. TypeVars, could protocols be used to define the shape of those types to avoid needing to import those packages?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions