Error [No module named 'pyaudioop']

ModuleNotFoundError: No module named 'pyaudioop' の直し方(Python 3.13 で pydub が止まる)

FIX SUMMARY verified
Applies when
python@sha256:9662417aace5ae7b8e2609cce472b72a8958e134ba372808abe9cc1a0c0125e6pydub 0.25.1 on Python 3.13 (audioop was removed from the standard library in 3.13; pydub falls back to pyaudioop, which it neither ships nor declares)moving a pydub project from Python 3.12 to 3.13 — pip install still succeeds and only `import pydub` stops, and the exception that Python prints last names pyaudioop rather than the module that was actually removed

Verified: reproduced in python@sha256:9662417aace5ae7b8e2609cce472b72a8958e134ba372808abe9cc1a0c0125e6, then the No module named 'pyaudioop' signature was gone after the fix (exit 0).

Python を 3.13 に上げてから、import pydub だけで次のエラーが出て止まります。最後の行は pyaudioop ですが、直す対象は1つ上のトレースバックに出ている audioop のほうです。

Traceback (most recent call last):
  File "/usr/local/lib/python3.13/site-packages/pydub/utils.py", line 14, in <module>
    import audioop
ModuleNotFoundError: No module named 'audioop'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
    import pydub
  File "/usr/local/lib/python3.13/site-packages/pydub/__init__.py", line 1, in <module>
    from .audio_segment import AudioSegment
  File "/usr/local/lib/python3.13/site-packages/pydub/audio_segment.py", line 11, in <module>
    from .utils import mediainfo_json, fsdecode
  File "/usr/local/lib/python3.13/site-packages/pydub/utils.py", line 16, in <module>
    import pyaudioop as audioop
ModuleNotFoundError: No module named 'pyaudioop'

pyaudioop という名前で PyPI を探しても、入れるべきパッケージは見つかりません。標準ライブラリにも、その名前のモジュールはありません。一方で、pydub パッケージの中には pyaudioop.py というファイルが実際に入っています(site-packages/pydub/pyaudioop.py)。在るのにトップレベルの名前としては見つからない——この食い違いが、エラーの結論を原因から引き離しています。

pip install pydub 自体は成功します。止まるのは import の時点だけです。

直し方の要点を先に

pydub はそのままで、audioop-lts を入れます。

pip install audioop-lts

実測では、pydub==0.25.1 を固定したまま audioop-lts==0.2.2 を追加すると、Python 3.13 で import pydub が終了コード 0 で通りました。動かしたのは追加パッケージだけで、pydub の版も Python の版も下げていません。

requirements.txt に書くなら、Python 3.13 以上でだけ入るようにします。audioop-lts は 3.13 以上を対象にしたパッケージなので、3.12 以下も動かす構成では条件を付けます。

pydub==0.25.1
audioop-lts==0.2.2; python_version >= "3.13"

なぜ pyaudioop という名前が出るのか

pydub/utils.py は、先に標準ライブラリの audioop を読もうとし、失敗したときだけ pyaudioop を代わりに読む書き方になっています。上のトレースバックの 14 行目と 16 行目がその2段です。

Python 3.12 までは1段目の import audioop が成功するので、2段目は実行されません。3.13 で audioop が無くなると1段目が失敗し、フォールバックの import pyaudioop as audioop まで進みます。

このフォールバック先のファイルは、pydub の中に実在します。 それでも失敗するのは、import pyaudioop がトップレベルのモジュール名を探す絶対 import だからです。pyaudioop.py は pydub パッケージの中にあるので、この書き方では見つかりません。同じ場所から読むなら from . import pyaudioop という相対 import になります。pydub 0.25.1 のこの2行は、暗黙の相対 import が使えた Python 2 の書き方のまま残っているもので、フォールバック自体が Python 3 では機能しません。

Python が最後に表示するのは2段目の例外です。そのため、実際に消えたモジュール(audioop)ではなく、届かなかったフォールバック先の名前(pyaudioop)がエラーの結論として出ます。 検索してもほとんど情報が出ないのは、pyaudioop が PyPI にも標準ライブラリにも存在しない名前だからです。

During handling of the above exception, another exception occurred: の上を読むと、1段目に No module named 'audioop' が残っています。原因はそちらです。

なぜ Python 3.13 で出るのか

引き金は Python の版です。Python 3.12 では、同じ pydub==0.25.1 を入れても import pydub は通ります(3.12 にはまだ audioop がある)。3.13 に上げた後だけ、同じ依存構成で import が止まります。

audioop は音声データを扱う標準ライブラリでした。公式ドキュメントは、3.11 で非推奨、3.13 で削除と述べています。PEP 594(dead batteries)による一括削除の一部で、同じ 3.13 で他のモジュールも消えています。削除された標準ライブラリの一覧と受け皿パッケージの対応は Python 3.13 で cgi モジュールが削除された にまとめてあります。

pydub を上げる形では直りません。 PyPI に出ている pydub は 0.25.1 が最上位で、版指定なしで入れても同じ 2 段の import 連鎖になります(上流が追随版を出したら、この前提は変わります。pip index versions pydub で最上位が 0.25.1 のままかを確認してください)。直すのは audioop を戻す側です。

同梱の pyaudioop.py を相対 import へ書き換えるパッチは、本記事では扱いません。 site-packages の中を書き換える形になり、再インストールで消えます。その経路が音声処理まで通るかも検証していません(同梱の実装は Python 2 時代のもので、audioop-lts のような CPython 由来の移植ではありません)。

なお、PEP 594 で消えたモジュールの受け皿は多くが standard- を付けた名前ですが、audioop はその規則から外れます。standard-audioop は存在しないので、名前を組み立てて打つと外します(受け皿名の一覧はハブ記事の表にあります)。

切り分け

  • エラーが No module named 'audioop' で終わっていて、pydub が出てこない → pydub 以外のライブラリが audioop を読んでいます。直し方(audioop-lts を入れる)は同じです。読んでいるライブラリはトレースバックの File の行で分かります。
  • トレースバックの最後が、消えたモジュール名そのもので終わっている(No module named 'imghdr' など)→ 同じ PEP 594 の削除ですが、フォールバックを挟まないぶん原因が直接見えている形です。その型は imghdr が依存ライブラリ経由で落ちる と telnetlib が依存ライブラリ経由で落ちる にあります。そちらは依存ライブラリを 3.13 対応版へ上げると直りますが、pydub には追随版がありません。
  • pip install pydub の時点で失敗している → 別の問題です。この記事の境界では install は成功し、import だけが止まります。
  • audioop-lts を入れたのに No module named 'audioop' のまま → その Python が 3.13 以上か確認してください。audioop-lts は 3.13 以上向けで、複数の Python が入った環境では pip と python が別の実体を指していることがあります。python -m pip install audioop-lts の形にすると、実行している Python に入ります。
  • 音を扱う処理そのものがエラーになる → 本記事で確認したのは import pydub が通るところまでで、pydub の各機能が audioop-lts 上で期待どおり動くかは検証していません。pydub issue #839 には audioop-lts を入れたあと AudioSegment.from_file まで通ったという報告があります(errfix の実測ではなく、報告です)。
  • ffmpeg が無いという警告が出る → pydub は音声の変換に外部の ffmpeg を使います。これは標準ライブラリの削除とは別の層で、この記事の境界には含まれません。

検証環境

  • image: python(digest 固定 sha256:9662417a...、Python 3.13)、ネットワーク有り(PyPI から取得するため)
  • 再現:pydub==0.25.1 を入れて import pydub → ModuleNotFoundError: No module named 'pyaudioop' で終了コード 1
  • 修正:同じ pydub==0.25.1 のまま audioop-lts==0.2.2 を追加して import pydub; import audioop → 終了コード 0
  • 版の対照:python:3.12.12-slim で同じ pydub==0.25.1 を入れて import pydub → 終了コード 0

再現から修正までは errfix の検証ハーネスが機械的に確認しています。reproduce と fix の差は追加した audioop-lts だけで、Python のイメージ・pydub の版・実行する import は同一です。audioop が 3.11 で非推奨・3.13 で削除であることは Python 公式ドキュメントによります。pydub 側で同じ import 連鎖が報告されていることは pydub issue #839 で確認しました。確認したのは import が通るところまでで、pydub の音声処理機能の動作は検証していません。

検証(machine-verified)

この修正は python@sha256:9662417aace5ae7b8e2609cce472b72a8958e134ba372808abe9cc1a0c0125e6 のバージョン固定コンテナ内で再現し、修正後に No module named 'pyaudioop' のシグネチャが消えることを機械で確認しています。

verify — run-case.mjs
$ node run-case.mjs python/audioop-removed-pydub-python-313
● reproduce No module named 'pyaudioop' present ✓
● apply fix exit 0
● re-run No module named 'pyaudioop' gone ✓
PASS verified · python@sha256:9662417aace5ae7b8e2609cce472b72a8958e134ba372808abe9cc1a0c0125e6 · signature gone

確認したのは上のイメージの中だけです。別の環境で直らなかった、記述が違う、という場合は 報告してください(対象と検証イメージは件名・本文に入ります)。