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 が予告なしに落ちたように見えるのは、imghdr の DeprecationWarning が 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-imghdr で import 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 imghdrがNo 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.py の import imghdr から確認しています。urllib3==1.26.20 は、python-telegram-bot 13.15 を 3.13 上で動かすと imghdr とは別に出る互換性問題を避け、imghdr の 1 点だけを検証するために両フェーズへ固定したものです。直し方1の「新しい版は imghdr を読まない」は、現行の python-telegram-bot が python:3.13.14-slim で import telegram を通すことを別途実測して確認しました。PEP 594 による削除の一覧や DeprecationWarning の挙動は cgi 記事に沿います。