Skip to content

fix: Python 3.14 compatibility and test suite correctness - #2

Merged
black-210 merged 1 commit into
black-210:mainfrom
blshkv:fix/python314-compatibility
Sep 21, 2026
Merged

black-210 merged 1 commit into
black-210:mainfrom
blshkv:fix/python314-compatibility

Conversation

@blshkv

@blshkv blshkv commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR fixes 8 bugs that make VULTURE fail on Python 3.14 and break the test suite on all Python versions. Every issue was found during packaging for the Pentoo Linux overlay and tested deeply — the full suite runs 63 passed, 2 skipped on Python 3.14.7 after these changes.


1. Python 3.14 — sys.modules registration missing before exec_module (3 files)

chemical_rf/__init__.py, forensics/__init__.py, lab/__init__.py all load a legacy .py sibling via importlib without registering the module in sys.modules first. Python 3.14 changed dataclasses._is_type to look up cls.__module__ in sys.modules; without the registration every @dataclass in those modules raises TypeError.

Fix: sys.modules[_spec.name] = _legacy before exec_module.

2. materials.py — reflection_coefficient undefined, absorption_coefficient broken

absorption_coefficient calls reflection_coefficient which doesn't exist in the file → NameError on import. __init__.py and pipeline.py also import reflection_coefficient by name.

Fix: add reflection_coefficient as (Z_L - Z_0) / (Z_L + Z_0) and rewrite absorption_coefficient as 1 - abs(gamma)**2.

3. cli.py — lab_cli imported but never registered

from vulture.lab_cli import lab_cli is present but cli.add_command(lab_cli, name="lab") is missing → vulture lab silently unavailable.

4. physics_laboratory.py — wrong dict key; dead instance methods cause infinite recursion

  • calculate_link_budget returns 'margin_db' but all callers expect 'link_margin_db'.
  • Three instance methods on RadarSimulator are defined after the correct @staticmethod implementations. Each returns a lambda immediately (unreachable code below), and the final duplicate calculate_radar_range shadows the static version and recurses infinitely.

5. fingerprint.py — rfft rejects complex input; dead code raises ValueError

  • np.fft.rfft on complex64 IQ data raises TypeError — should be np.fft.fft / np.fft.fftfreq.
  • Two dead lines in similarity() cast hex SHA-256 strings to np.uint8 → ValueError; variable d is never used.

6. timeseries_engine.py — circular buffer returns empty slice after full write

add_data was missing the n >= buffer_size case. After filling the buffer it set position = 0, so buffer[:position] returned an empty array. Fix: set position = buffer_size and add an explicit branch for the overflow case.

7. pytest.ini — contains a Python docstring, not an INI section

The file held """Pytest markers…""" — a string literal pytest silently ignores. Replaced with [pytest].

8. tests/conftest.py — conftest_enterprise.py never auto-loaded

pytest only discovers files named conftest.py. All fixtures in conftest_enterprise.py (bpsk_signal, qpsk_signal, chirp_signal, burst_signal, multipath_signal) were invisible to the test runner. Merged into conftest.py and extended base fixtures to the sizes the enterprise suite requires.


Test result: 63 passed, 2 skipped on Python 3.14.7 (was: import errors + multiple test failures before this patch).

SPDX-License-Identifier: AGPL-3.0-only

Python 3.14 changed dataclasses._is_type to require cls.__module__ to
exist in sys.modules when exec_module is called.  Three packages load
legacy .py files alongside same-named packages via importlib without
registering the module in sys.modules first, breaking @DataClass.

Fix all three by inserting sys.modules[_spec.name] = _legacy before
exec_module in chemical_rf/__init__.py, forensics/__init__.py and
lab/__init__.py.

Additional fixes uncovered during testing:

materials.py: absorption_coefficient referenced an undefined
reflection_coefficient function; add reflection_coefficient as the
canonical Γ = (Z_L - Z_0)/(Z_L + Z_0) formula and rewrite
absorption_coefficient to use it.

__init__.py (chemical_rf): also export absorption_coefficient which
was already used in tests.

cli.py: wire lab_cli sub-command that was imported but never added.

physics_laboratory.py: calculate_link_budget returned 'margin_db' but
callers (and tests) expected 'link_margin_db'; rename the key.  Remove
three dead instance methods on RadarSimulator that shadowed the correct
@staticmethod implementations and contained unreachable code after
early return statements.

fingerprint.py: np.fft.rfft rejects complex64 input; switch to
np.fft.fft / np.fft.fftfreq.  Remove two dead lines in similarity()
that tried to cast hex SHA-256 digest strings to np.uint8.

timeseries_engine.py: add_data set position=0 after a full-buffer
write (n >= buffer_size), causing subsequent reads via
buffer[:position] to return an empty slice.  Set position=buffer_size
instead so the buffer is correctly reported as full.  Also handle the
previously-missing case where n >= buffer_size (overflow without wrap)
with an explicit branch.

pytest.ini: replace Python docstring (which pytest silently ignores)
with a valid [pytest] INI section.

tests/conftest.py: merge fixtures from conftest_enterprise.py which
pytest never auto-loaded; extend base fixtures to sizes required by the
enterprise test suite (1 M-sample signals, richer iq_data).

Tested: 63 passed, 2 skipped on Python 3.14.7.

SPDX-License-Identifier: AGPL-3.0-only

@black-221 black-221 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok good

@hatraa757-cpu hatraa757-cpu left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good

@black-88888 black-88888 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might accept, but I'm not sure.

@black-210
black-210 merged commit 557eddc into black-210:main Sep 21, 2026
@blshkv
blshkv deleted the fix/python314-compatibility branch September 21, 2026 12:53
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.

5 participants