Skip to content

Fix voice sample validation on Python 3.13 (fixes #852)#853

Open
maskedsyntax wants to merge 1 commit into
jamiepine:mainfrom
maskedsyntax:fix/audioop-python-3-13
Open

Fix voice sample validation on Python 3.13 (fixes #852)#853
maskedsyntax wants to merge 1 commit into
jamiepine:mainfrom
maskedsyntax:fix/audioop-python-3-13

Conversation

@maskedsyntax

@maskedsyntax maskedsyntax commented Jul 5, 2026

Copy link
Copy Markdown

Summary

Fixes #852. Python 3.13 dropped audioop from the standard library, but reference audio validation still needs it through librosa and audioread. Uploading a voice sample then fails with No module named 'audioop'.

This adds the audioop-lts backport for Python 3.13 and above, and tells PyInstaller to bundle audioop when building on those versions.

Test plan

  • Reproduced the failure on Python 3.13.14 without audioop-lts: validation returns Error validating audio: No module named 'audioop'
  • Confirmed the fix: validation passes after installing audioop-lts
  • pytest backend/tests/test_audioop_python313.py -v on Python 3.13 (5 passed)
  • pytest backend/tests/test_audio_preprocess.py -v on Python 3.13 (9 passed)
  • Build arg tests pass on Python 3.12 (3 passed, 2 skipped)

Summary by CodeRabbit

  • Bug Fixes
    • Improved compatibility with Python 3.13+ by ensuring audio processing works when the standard library audioop module is unavailable.
    • Build packages now include the needed audio support automatically on newer Python versions, reducing runtime and packaging issues.
    • Updated dependency handling so the correct audio compatibility package is installed only for Python 3.13 and later.

@coderabbitai

coderabbitai Bot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e9cad93c-22cd-47f7-bc21-c8c7b0828721

📥 Commits

Reviewing files that changed from the base of the PR and between ad8d68b and bf74939.

📒 Files selected for processing (3)
  • backend/build_binary.py
  • backend/requirements.txt
  • backend/tests/test_audioop_python313.py
🚧 Files skipped from review as they are similar to previous changes (3)
  • backend/build_binary.py
  • backend/requirements.txt
  • backend/tests/test_audioop_python313.py

📝 Walkthrough

Walkthrough

Adds a Python 3.13+ conditional dependency on audioop-lts in requirements.txt, extends PyInstaller build arguments with a hidden import for audioop on Python 3.13+, and adds a new pytest module regression-testing both changes plus reference audio validation behavior.

Changes

Audioop Python 3.13 compatibility fix

Layer / File(s) Summary
Dependency and build config
backend/requirements.txt, backend/build_binary.py
Adds a conditional audioop-lts>=0.2.1 requirement for Python 3.13+ and a matching PyInstaller hidden-import guard using sys.version_info >= (3, 13).
Regression tests
backend/tests/test_audioop_python313.py
New test module with fixtures verifying the requirements entry, runtime reference audio validation without audioop-related errors, and PyInstaller build args including or excluding the audioop hidden import based on Python version.

Estimated code review effort: 1 (Trivial) | ~5 minutes

Related Issues: #852

Suggested labels: bug, python3.13, dependencies, tests

Suggested reviewers: jamiepine

🐰 A hop, a skip, a version check,
audioop's gone, but we've got a tech-neck fix—
lts to the rescue, hidden imports too,
tests all passing, nothing left askew.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: fixing Python 3.13 voice sample validation tied to issue #852.
Linked Issues check ✅ Passed The PR addresses #852 by adding audioop-lts for Python 3.13+ and bundling audioop for PyInstaller, restoring voice sample validation.
Out of Scope Changes check ✅ Passed The changes stay focused on the Python 3.13 audioop compatibility fix and related regression tests.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
backend/tests/test_audioop_python313.py (1)

71-83: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Duplicate FakeVersionInfo class in both build-arg tests.

Extract into a shared module-level helper/fixture to avoid the identical class definition in test_pyinstaller_includes_audioop_on_python_313 and test_pyinstaller_omits_audioop_on_python_312.

♻️ Suggested consolidation
+class _FakeVersionInfo(tuple):
+    `@property`
+    def major(self):
+        return self[0]
+
+    `@property`
+    def minor(self):
+        return self[1]
+
+    `@property`
+    def micro(self):
+        return self[2]
+
+
 class TestAudioopBuildArgs:
     `@staticmethod`
     def _hidden_imports(args):
         imports = []
         for i, arg in enumerate(args):
             if arg == "--hidden-import" and i + 1 < len(args):
                 imports.append(args[i + 1])
         return imports

     def test_pyinstaller_includes_audioop_on_python_313(self):
-        class FakeVersionInfo(tuple):
-            `@property`
-            def major(self):
-                return self[0]
-
-            `@property`
-            def minor(self):
-                return self[1]
-
-            `@property`
-            def micro(self):
-                return self[2]
-
-        fake_313 = FakeVersionInfo((3, 13, 0, "final", 0))
+        fake_313 = _FakeVersionInfo((3, 13, 0, "final", 0))

Also applies to: 99-111

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/tests/test_audioop_python313.py` around lines 71 - 83, The identical
FakeVersionInfo helper is duplicated across the two PyInstaller audioop tests,
so move it to a shared module-level helper or fixture and reuse it from both
test_pyinstaller_includes_audioop_on_python_313 and
test_pyinstaller_omits_audioop_on_python_312. Keep the tuple-based version
behavior the same, but define it once near the test helpers so the tests
reference the same FakeVersionInfo symbol instead of re-declaring the class.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@backend/tests/test_audioop_python313.py`:
- Around line 71-83: The identical FakeVersionInfo helper is duplicated across
the two PyInstaller audioop tests, so move it to a shared module-level helper or
fixture and reuse it from both test_pyinstaller_includes_audioop_on_python_313
and test_pyinstaller_omits_audioop_on_python_312. Keep the tuple-based version
behavior the same, but define it once near the test helpers so the tests
reference the same FakeVersionInfo symbol instead of re-declaring the class.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 13f1d4dd-4669-488b-b89c-aa1939a6e580

📥 Commits

Reviewing files that changed from the base of the PR and between f2cf2a7 and ad8d68b.

📒 Files selected for processing (3)
  • backend/build_binary.py
  • backend/requirements.txt
  • backend/tests/test_audioop_python313.py

@maskedsyntax maskedsyntax force-pushed the fix/audioop-python-3-13 branch from ad8d68b to fda8d82 Compare July 5, 2026 17:32
Python 3.13 removed audioop from the standard library, which broke reference
audio validation when adding voice samples. Add the audioop-lts backport for
3.13+ installs and bundle audioop in PyInstaller builds on the same versions.
@maskedsyntax maskedsyntax force-pushed the fix/audioop-python-3-13 branch from fda8d82 to bf74939 Compare July 5, 2026 17:33
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.

Adding voice sample fails: No module named 'audioop' (Python 3.13) — v0.5.0, macOS Apple Silicon

1 participant