Skip to content

Drop pynput dependency to fix Linux installs#323

Open
m9h wants to merge 1 commit intoNeuroTechX:masterfrom
m9h:fix/linux-install-drop-pynput
Open

Drop pynput dependency to fix Linux installs#323
m9h wants to merge 1 commit intoNeuroTechX:masterfrom
m9h:fix/linux-install-drop-pynput

Conversation

@m9h
Copy link
Copy Markdown

@m9h m9h commented Apr 18, 2026

Summary

  • pynput pulls in evdev, which fails to build on many modern Linux toolchains (missing SND_PROFILE_RING symbol when the build environment's kernel headers or conda sysroot is older than the one evdev 1.9 expects). Users hitting this see a wall of C compile errors at install time, and pip install eeg-notebooks becomes non-functional on Fedora 43 + miniconda, and on several fresh-install Ubuntu/Debian setups.
  • pynput is only used in two places: the "press C + enter within 5s to cancel" prompt inside check_report in analysis/utils.py and its twin in analysis/streaming_utils.py. Neither benefits from pynput's global-keyboard hook — a plain stdin read suffices.

This PR replaces both callsites with a small wait_for_cancel(timeout, cancel_key) helper (eegnb/utils/cancel.py, ~40 lines) that reads stdin on a daemon thread. Cross-platform, zero new dependencies, identical observable UX.

It also makes the top-level import pyxid2 in devices/eeg.py lazy: pyxid2 is only exercised by the Cedrus XID response-box path (_init_xid), and is not needed for Muse / OpenBCI / Unicorn. Wrapping the import in try/except unblocks environments where the Cedrus C library isn't installable while still raising a clear ImportError if the user actually invokes _init_xid without it.

No behaviour change on the supported backends.

Test plan

  • `pip install -e .[streamstim]` now succeeds on Fedora 43 + Python 3.11 where it previously errored on the evdev build.
  • `python -c "from eegnb.analysis.utils import check_report"` imports without pynput installed.
  • `python -c "from eegnb.devices.eeg import EEG"` imports without pyxid2 installed.
  • The cancel prompt still cancels the signal-quality loop when the user types `c` + enter within 5s; still times out silently otherwise.

🤖 Generated with Claude Code

pynput pulls in `evdev`, which currently fails to build from source
under several common Linux toolchains (the symbol `SND_PROFILE_RING`
used in evdev 1.9's input.h binding is missing from older kernel
headers and conda's sysroot). Users hitting this see a wall of C
compile errors at `uv pip install`/`pip install` time.

The only two callsites of pynput in the tree are `check_report`-style
"press C + enter within 5 seconds to cancel" prompts in
`analysis/utils.py` and `analysis/streaming_utils.py`. Both are
replaced with a small `wait_for_cancel(timeout, cancel_key)` helper
in the new `eegnb/utils/cancel.py` that reads stdin on a daemon
thread. Cross-platform, zero new dependencies, same observable UX.

Also guards the unconditional `import pyxid2` in `devices/eeg.py`
behind a try/except. pyxid2 is only exercised by the Cedrus
response-box path (`_init_xid`) and is not needed for the main
Muse / OpenBCI / Unicorn pipelines; it was blocking imports in
environments where the Cedrus C library isn't available. A clear
ImportError is raised if the user actually invokes `_init_xid`
without the library installed.

No behaviour change on the supported backends.
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.

1 participant