Libusb and the psychtoolbox wheel in psychopy?

Hi, I am porting this high-speed low-cost eyetracker (High Speed eye tracking system) to work in PTB. The sample code is in Psychopy (which I need to understand so I want to run it, but I’ve never used psychopy before), and trying to pip install psychopy it is the psychtoolbox wheel fails to install:

Collecting psychtoolbox
  Using cached psychtoolbox-3.0.18.2.zip (2.9 MB)
  Preparing metadata (setup.py) ... error
  error: subprocess-exited-with-error

  × python setup.py egg_info did not run successfully.
  │ exit code: 1
  ╰─> [15 lines of output]
      Traceback (most recent call last):
        File "<string>", line 2, in <module>
        File "<pip-setuptools-caller>", line 34, in <module>
        File "C:\Temp\pip-install-7aczrn53\psychtoolbox_baf57c935d5748e0a9f969235d6b9d34\setup.py", line 109, in <module>
          shutil.copy('PsychSourceGL/Cohorts/libusb1-win32/MS64/dll/libusb-1.0.dll',
        File "C:\Users\Ian\scoop\apps\python\current\Lib\shutil.py", line 419, in copy
          copyfile(src, dst, follow_symlinks=follow_symlinks)
        File "C:\Users\Ian\scoop\apps\python\current\Lib\shutil.py", line 256, in copyfile
          with open(src, 'rb') as fsrc:
               ^^^^^^^^^^^^^^^
      FileNotFoundError: [Errno 2] No such file or directory: 'PsychSourceGL/Cohorts/libusb1-win32/MS64/dll/libusb-1.0.dll'
      Platform reported as: Windows

I know this isn’t a PTB problem but a python packaging issue, but if anyone has any python packaging knowledge could point me to how to fix this I’d be much obliged…

Hi @Ian-Max-Andolina, it looks like the source install (.zip file) is missing the libusb DLL. What version of Python are you using (python --version)? For the majority of platforms, pip install psychtoolbox would give the user a prebuilt package, but apparently that didn’t happen in this case.

I have a pretty good idea of how to resolve the source install issue (the MANIFEST.in file fails to include shared libraries), but there are a few ways to work around in the meanwhile…

  • Download the artifacts from here, extract the proper wheel (“psychtoolbox-3.0.19.0-cp36-cp36m-win_amd64.whl” if using Python 3.6, “psychtoolbox-3.0.19.0-cp37-abi3-win_amd64.whl” for anything newer), and invoke pip on that file, i.e. pip install psychtoolbox...whl . This will install a prebuilt psychtoolbox, and should work for the vast majority of cases on Windows? These files will live on PyPI soon™
  • Build directly from the repository. If you have a local copy of the psychtoolbox source, navigate to the top level of that directory (i.e. where the setup.py file is) and run pip install . . Otherwise, you can directly invoke pip install git+https://github.com/kleinerm/psychtoolbox-3, which will download a temporary copy of the source and install from there. IIRC, this requires you to have Microsoft’s compilers installed (see here), so this option has slightly higher activation energy if you don’t happen to have these tools installed yet.
1 Like

Wow, thanks for the speedy reply. I am stuck using Windows 11, and ended up with Python 3.11 using scoop which I now understand is not compatible with Psychopy… I normally use pyenv on linux and macOS to manage my Python versions but it appears not to work at all on Windows for me. I’m not sure what the best Windows tool is to manage runtime versions…

I will try your instructions when I get back into the lab. Thank you again!

Just a small update, uninstalling the default python from scoop and installing 3.8 and psychopy seems to have installed. Is that expected?

That is expected. The current version on PyPI has wheels up to Python 3.10, so trying install on 3.8 will pick up the precompiled wheel. There isn’t a wheel that will work for 3.11 yet, so pip tries to install from source (which is currently broken for Windows because of the missing DLLs).

The impending set of new wheels for PyPI will use a special subset of the CPython API, which allows us to build a single wheel that is compatible with future versions of Python 3.x, rather than needing to build new ones each time a new Python version is released.

They have a fairly large number of dependencies, and some of those haven’t caught up to recent Python versions yet (see here). Sticking with 3.8 is probably least friction for now.

1 Like