Skip to content

Fix CedRawIO with sonpy >= 1.9.12 and re-enable the CED tests - #1891

Open
AxelNoun wants to merge 3 commits into
NeuralEnsemble:masterfrom
AxelNoun:fix/cedrawio-sonpy-namespace
Open

Fix CedRawIO with sonpy >= 1.9.12 and re-enable the CED tests#1891
AxelNoun wants to merge 3 commits into
NeuralEnsemble:masterfrom
AxelNoun:fix/cedrawio-sonpy-namespace

Conversation

@AxelNoun

Copy link
Copy Markdown

Closes #1890.

sonpy 1.9.12 reorganised its package layout and dropped the lib namespace that
cedrawio.py relies on, so every sonpy.lib.* access raises
AttributeError: module 'sonpy' has no attribute 'lib'.

While preparing the fix I found that the CED tests could not have caught this, for two
independent reasons — so this PR fixes the reader and restores the test coverage that would
have flagged it.

1. neo/rawio/cedrawio.py — resolve the namespace

A cached _get_sonpy_namespace() helper probes three candidates in order:

candidate covers
sonpy.lib <= 1.9.5, the old per-platform dispatch
sonpy >= 1.9.12 on Windows and macOS (from .sonpy import *)
sonpy.sonpy >= 1.9.12 on Linux, whose wheel ships an empty __init__.py

The third is not redundant: the cp314-manylinux_2_39_x86_64 wheel has a 0-byte
__init__.py, so neither sonpy.lib nor sonpy.SonFile resolves there. If none of the
three exposes SonFile, an ImportError naming all three is raised, rather than letting an
AttributeError surface from the middle of _parse_header.

2. Both CED test guards

There are two, and each fails differently with 1.9.12:

  • neo/test/iotest/test_cedio.py replicated the old per-platform dispatch
    (import sonpy.linux.sonpy, …), which no longer exists → HAVE_SONPY = False → skipped.
  • neo/test/rawiotest/test_cedrawio.py used a bare import sonpy, which succeeds with
    1.9.12 → HAVE_SONPY = True → the test would run and fail with the AttributeError.

Both now delegate to _get_sonpy_namespace(), so "sonpy is usable" has one definition.

3. pyproject.toml — the test extra never installed sonpy

"sonpy;python_version<'3.10'",

with requires-python = ">=3.10". The marker cannot be satisfied, so sonpy is absent from
every CI run and both guards were moot regardless of how they were written. This is why the
breakage went unnoticed.

Changed to match where sonpy actually publishes usable wheels:

"sonpy; platform_system=='Windows' or python_version>='3.14'",

1.9.12 ships win_amd64 wheels for cp39–cp314, but manylinux and macosx only for cp314.
The marker is deliberately not just "sonpy": on Linux 3.10–3.13 pip would fall back to the
source distribution, which ships a Windows .pyd (verified: PE32+ executable (DLL) […] for MS Windows) and produces an unusable install.

The practical effect is that the automatic ubuntu-latest / Python 3.14 CI job will now
install sonpy and actually exercise CedRawIO.

Verification

The existing test suite goes from failing to passing. Windows, Python 3.12, sonpy 1.9.12,
against master (35cbce7):

pytest neo/test/rawiotest/test_cedrawio.py -v
unpatched FAILEDAttributeError: module 'sonpy' has no attribute 'lib' at cedrawio.py:72
patched PASSED (1.07 s) — test_read_all across all three spike2 entities

That covers both .smrx and the two .smr entities, so the reader is exercised end to end
and not just at import time.

Additionally:

  • Windows, Python 3.10–3.14, sonpy 1.9.12: sonpy.lib absent on all five; the compiled
    library reads spike2/m365_1sec.smrx correctly through the new namespace
    (GetOpenError() == 0, MaxChannels() == 101), confirming an import-path problem rather
    than a functional regression in sonpy.
  • Linux x86_64, Python 3.14, sonpy 1.9.12: the helper resolves to sonpy.sonpy; SonFile,
    DataType.Adc, DataType.AdcMark and MarkerFilter are all reachable, and
    CedRawIO.parse_header() runs to completion instead of raising.
  • Both guards checked in both directions: HAVE_SONPY is True with sonpy 1.9.12 present
    and False when sonpy cannot be imported.
  • The proposed marker evaluates True exactly where a usable wheel exists, across the six
    platform/version combinations in Neo's support range.
  • black --line-length 120 --check clean on all changed files.
  • After the three commits: pytest neo/test/rawiotest/test_cedrawio.py neo/test/iotest/test_cedio.py -v8 passed.

Not covered

macOS is untested. It is the one platform where the 1.9.12 wheel exists only for cp314, so
3.10–3.13 are excluded by the marker there. Happy to run it if someone has a machine.

Open questions

  1. Is platform_system=='Windows' or python_version>='3.14' acceptable, or would you rather
    keep the test extra minimal and add sonpy only to the CI workflow?
  2. Should the ced extra (line 101, currently a bare "sonpy") get the same marker for
    consistency? I left it alone to keep the diff focused.

AxelNoun and others added 3 commits July 30, 2026 18:52
sonpy 1.9.12 dropped the 'lib' namespace that cedrawio.py used, so every
sonpy.lib.* access raised AttributeError. Resolve the namespace once,
probing sonpy.lib, sonpy and sonpy.sonpy in turn: the last is needed on
Linux, where the 1.9.12 wheel ships an empty __init__.py.

Refs NeuralEnsemble#1890

Co-authored-by: Cursor <cursoragent@cursor.com>
test_cedio.py replicated the old per-platform sonpy dispatch and skipped
with 1.9.12; test_cedrawio.py guarded on a bare 'import sonpy', which
succeeds with 1.9.12 so the test would run and fail. Both now delegate to
_get_sonpy_namespace().

Refs NeuralEnsemble#1890

Co-authored-by: Cursor <cursoragent@cursor.com>
The test extra declared sonpy;python_version<'3.10' while the project
requires >=3.10, so sonpy was never installed and the CED tests never ran.
Target the platform/version combinations sonpy actually publishes wheels
for; the sdist ships a Windows .pyd and is not usable elsewhere.

Refs NeuralEnsemble#1890

Co-authored-by: Cursor <cursoragent@cursor.com>
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.

CedRawIO is broken with sonpy >= 1.9.12: the lib namespace no longer exists

1 participant