Error [No module named 'imghdr']

ModuleNotFoundError: No module named 'imghdr' の直し方(Python 3.13 で、自分が使っていない imghdr が依存ライブラリ経由で落ちる)

FIX SUMMARY verified
Applies when
python:3.13.14-slimCPython 3.13 (imghdr removed by PEP 594) x python-telegram-bot 13.15importing an old dependency (python-telegram-bot 13.15) that does 'import imghdr' internally, on Python 3.13 where imghdr is removed

Verified: reproduced in python:3.13.14-slim, then the No module named 'imghdr' signature was gone after the fix (exit 0).

Python を 3.13 に上げてから、import telegram(python-telegram-bot)のようにライブラリを読み込むだけで次のエラーが出て止まることがあります。

Traceback (most recent call last):
  File "<string>", line 1, in <module>
    import telegram
  File "/usr/local/lib/python3.13/site-packages/telegram/__init__.py", line 69, in <module>
    from .files.inputfile import InputFile
  File "/usr/local/lib/python3.13/site-packages/telegram/files/inputfile.py", line 22, in <module>
    import imghdr
ModuleNotFoundError: No module named 'imghdr'

自分のコードに import imghdr は 1 行も無いのに落ちます。トレースバックの最後の File を見ると、import imghdr しているのは site-packages の中、つまり依存ライブラリです。imghdr は標準ライブラリだったモジュールで、PEP 594(dead batteries)により Python 3.13 が標準ライブラリから削除しました。古い python-telegram-bot(13.15)は、import telegram の途中で imghdr を読み込むため、3.13 では読み込みが完了しません。

直し方は2つで、依存ライブラリを 3.13 対応版へ上げるか、上げられないならバックポート standard-imghdr を入れて imghdr を戻すかです。

なぜ起きるのか:削除された標準ライブラリを、依存ライブラリが読んでいる

imghdr は画像フォーマットを判定する標準ライブラリでした。PEP 594 が「使われていない標準ライブラリ(dead batteries)」として削除対象に挙げ、3.13 で削除されました。3.13 の Python には imghdr というモジュールが存在しません。

python-telegram-bot 13.15 は、送信ファイルの種類を判定するために telegram/files/inputfile.py の中で import imghdr しています。ライブラリを import telegram した時点でこのファイルも読み込まれるので、あなたが imghdr を直接使っているかどうかに関係なく、ライブラリの読み込み自体が ModuleNotFoundError で止まります。トレースバックの File の行が site-packages の中を指しているのはこのためです。

なぜ Python 3.13 で出るのか

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

  • Python を 3.12 から 3.13 へ上げた:ランタイムや CI/コンテナのイメージを新しくしたら、これまで動いていたライブラリの import が落ちる。
  • 手元は 3.12 のまま、CI やコンテナだけ 3.13:環境の Python 版が食い違い、片方だけ落ちる。python -V を両方で確認します。

なお、この import が予告なしに落ちたように見えるのは、imghdrDeprecationWarning が 3.11/3.12 で出ていたのに、依存ライブラリの中からの警告は Python の既定フィルタが隠すためです。この仕組みは同じ PEP 594 の No module named ‘cgi’ の直し方 で詳しく扱っています。

直し方1:依存ライブラリを 3.13 対応版へ上げる

imghdr を読んでいるのは python-telegram-bot なので、直せるのはライブラリの版です。新しい python-telegram-bot は imghdr への依存をやめています

pip install --upgrade python-telegram-bot

ただし python-telegram-bot は 13.x から 20.x 以降で全面的に非同期(async)へ書き直されていて、メジャーな API 変更があります。13.15 のコードをそのまま上げると、今度は自分のコード側の修正が必要になります。上げる場合は、ライブラリの移行ガイドに沿ってコードも直します。同じことは他の「古い版が削除済み標準ライブラリを読む」ライブラリにも当てはまり、まずそのライブラリに 3.13 対応版があるかを確認するのが本筋です。

直し方2:バックポート standard-imghdr を入れて、版を保つ

ライブラリをすぐに上げられない(API 変更の移行が終わっていない)場合は、削除された imghdrバックポート standard-imghdr で戻しますimport imghdr が再び通るようになり、python-telegram-bot 13.15 の読み込みがこの箇所で止まらなくなります。

pip install standard-imghdr

requirements.txt に加えるときは、なぜ入れているか(削除された標準ライブラリ imghdr のバックポート。ライブラリを 3.13 対応版へ上げたら外す)をコメントで添えます。これは古い版を延命するための当座の措置で、恒久策はライブラリの更新です。

バックポートは imghdr の壁を1つ越えるだけで、それで完了とは限りません。 3.13 に無いモジュールを読む古いライブラリは、imghdr 以外にも新しい Python と噛み合わない箇所を抱えていることがあります。実際この python-telegram-bot 13.15 は、standard-imghdr を入れて imghdr を通した先で、今度は vendoring された six が新しい urllib3 と噛み合わず別のエラーを出します(検証では urllib3==1.26.20 を合わせて回避しました)。つまり standard-imghdrimport telegram が通っても、その版のライブラリを 3.13 で使い続けると次の非互換に当たりうる——これがバックポートを「恒久策」にしない理由です。3.13 対応版へ上げれば、こうした玉突きの非互換ごと解消します。

パッケージ名は標準ライブラリのモジュール名とは違います。imghdr の受け皿は standard-imghdr で、pip install imghdr というパッケージはありません。他の削除済みモジュールのバックポート名(接頭辞が揃っていない点を含む)は、cgi 記事のバックポート表にまとめてあります。

切り分け(うまくいかないとき)

  • import telegram ではなく別のライブラリで同じ形が出るNo module named 'telnetlib'netmiko など)も同型で、古い依存が削除済みの標準ライブラリを読んでいます。原因も対処も同じです(No module named ‘telnetlib’ の直し方)。
  • imghdr 以外のモジュール名で落ちるcrypt / telnetlib / pipes / nntplib なども PEP 594 で 3.13 に削除されています。どのモジュールがどの版で消えたか、バックポート名の一覧は cgi 記事を参照してください。
  • standard-imghdr を入れたのに、今度は別のエラーで止まる:古いライブラリを新しい Python で動かすと、削除済み標準ライブラリ以外の非互換が続けて出ることがあります。その場合は、ライブラリを 3.13 対応版へ上げる直し方1に切り替えます。
  • pip install imghdrNo matching distribution found になる:モジュール名と同じ pip パッケージはありません。バックポートは standard-imghdr です。
  • 手元では動くのに CI やコンテナでだけ落ちる:Python の版が違います。3.13 のイメージに上げた直後に出るのが典型で、python -V を両方で確認します。

検証環境

  • python:3.13.14-slim、ネットワーク有り
  • 再現:pip install "python-telegram-bot==13.15" "urllib3==1.26.20" の後、python -c "import telegram"ModuleNotFoundError: No module named 'imghdr' で終了コード 1
  • 修正:同じ依存に standard-imghdr==3.13.0 を足すと、python -c "import telegram" が終了コード 0・シグネチャ消滅

再現から修正までは errfix の検証ハーネスが機械的に確認しています。版境界は、python:3.12.12-slim では同じ python-telegram-bot 13.15 で import telegram が通ること(3.12 には imghdr がある)を実測して裏づけました。依存側の呼び出し元は、トレースバックの telegram/files/inputfile.pyimport imghdr から確認しています。urllib3==1.26.20 は、python-telegram-bot 13.15 を 3.13 上で動かすと imghdr とは別に出る互換性問題を避け、imghdr の 1 点だけを検証するために両フェーズへ固定したものです。直し方1の「新しい版は imghdr を読まない」は、現行の python-telegram-bot が python:3.13.14-slimimport telegram を通すことを別途実測して確認しました。PEP 594 による削除の一覧や DeprecationWarning の挙動は cgi 記事に沿います。

検証(machine-verified)

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

verify — run-case.mjs
$ node run-case.mjs python/imghdr-removed-dependency-python-313
● reproduce No module named 'imghdr' present ✓
● apply fix exit 0
● re-run No module named 'imghdr' gone ✓
PASS verified · python:3.13.14-slim · signature gone

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