Python を 3.10 以降に上げてから、from collections import Mapping のようなインポートで次のエラーが出て止まることがあります。
ImportError: cannot import name 'Mapping' from 'collections' (/usr/local/lib/python3.10/collections/__init__.py)
Mapping だけでなく、MutableMapping・Sequence・Iterable・Callable など、同じ仲間(抽象基底クラス、ABC)でも同じ形で出ます。これは、これらの ABC が collections 直下から collections.abc へ移され、3.10 で直下からの参照が削除されたために起きます。書き換えるのは import 文の 1 行だけです。
なぜ移動したのか
Mapping などの ABC は、本来 collections.abc にあります。歴史的な経緯で collections 直下からも参照できていましたが、それは Python 3.3 の時点で非推奨とされ、「3.10 で動かなくなる」と警告され続けていました。予告どおり 3.10 で削除され、from collections import Mapping は ImportError になりました。
置き場所が変わっただけで、中身は同じです。collections.abc から取れば、そのまま動きます。
なぜ Python 3.10 以降で出るのか
同じインポートでも、Python 3.9 以前なら通ります(DeprecationWarning は出ますが動きます。この警告は python -c や __main__ では見えますが、通常の実行では既定で抑制されます)。エラーになるのは Python を 3.10 以降に上げた後です。手元やこれまでの環境が 3.9 以前なら踏みません。次のような形で表面化します。
- Python を 3.10 / 3.11 / 3.12 に上げた:ランタイムや CI のイメージを新しくしたら、古いインポートが動かなくなった、という形です。
- 落ちているのが自分のコードではなく、古い第三者ライブラリの中:長く更新されていないライブラリが
from collections import Mappingを使っていて、新しい Python で読み込めません。 - 手元は古い Python のまま、CI やコンテナだけ新しい:環境差で、片方だけ落ちます。
直し方1:インポート元を collections.abc に直す(基本)
自分のコードなら、インポート元を collections.abc に変えます。
# 変更前
from collections import Mapping, MutableMapping
# 変更後
from collections.abc import Mapping, MutableMapping
移動した主な ABC は次のとおりで、いずれも collections.abc から取ります。
| 直下から削除(3.10) | 正しいインポート元 |
|---|---|
Mapping / MutableMapping | collections.abc |
Sequence / MutableSequence | collections.abc |
Iterable / Iterator / Generator | collections.abc |
Callable / Hashable | collections.abc |
Set / MutableSet | collections.abc |
collections.OrderedDict や collections.defaultdict など、collections 本体のもの(ABC ではない)はそのままで、移動していません。変えるのは ABC のインポート元だけです。
なお、collections.abc は Python 3.3 から存在するため、from collections.abc import Mapping だけですべての 3.x(3.9 を含む)で動きます。3.9 から 3.10 への移行に限れば fallback は不要です。次の try/except が要るのは、Python 2 系まで同時に支えるライブラリの場合だけです。
try:
from collections.abc import Mapping
except ImportError: # collections.abc が無い古い環境(Python 2 系)
from collections import Mapping
直し方2:直せないのが依存ライブラリのとき
エラーが自分のコードではなく、入れた第三者ライブラリの中で出ているなら、コードは直せません。
- そのライブラリを新しくする:
pip install --upgrade <ライブラリ>。多くは 3.10 対応済みの版が出ています。まずこれを試します。 - どうしても上げられないなら、つなぎで Python を 3.9 以前にする:ただし 3.9 も新しいパッケージから外れていく版なので、ライブラリを更新するまでの当座の措置です。3.9 は 2025 年にサポートが終了(EOL)してセキュリティ更新も止まっているため、本番の恒久策にはせず、対応版が出るまでの短期の切り分けに限ります。
新しい Python を保ったままにできる直し方1(インポート修正/ライブラリ更新)が本筋で、Python を下げるのは当座の回避に留めます。
切り分け(うまくいかないとき)
Sequence・Iterable・Callableでも同じエラーが出る:どれも 3.10 でcollections直下から削除された ABC です。インポート元をcollections.abcに変えます。collections.abcに直したのに、まだ同じエラーが出る:別の箇所や、インポートされた別モジュールに古い書き方が残っています。from collections importをコード全体で検索して洗い出します。第三者ライブラリ内なら直し方2です。AttributeError: module 'collections' has no attribute 'Mapping'の形で出る:import collectionsしてからcollections.Mappingと属性アクセスしているケースです。原因は同じ(3.10 の削除)にあります。ここで注意したいのは、import collectionsだけではcollections.abcサブモジュールは読み込まれない点で、そのままcollections.abc.Mappingと書くと今度はAttributeError: module 'collections' has no attribute 'abc'になります。from collections.abc import Mappingに直すか、import collections.abcを明示してからcollections.abc.Mappingを使います。- Python を下げたら、他のパッケージが動かなくなった:新しいパッケージが 3.10 以降を要求しているケースです。Python を下げる方向でなく、直し方1(インポート修正/ライブラリ更新)へ切り替えます。
検証環境
python:3.10-slim、ネットワーク無し- 再現:
from collections import Mappingを実行すると、cannot import name 'Mapping' from 'collections'を出して終了コード 1 - 修正:
from collections.abc import Mappingにすると、終了コード 0
再現から修正までは errfix の検証ハーネスが機械的に確認しています。純粋な標準ライブラリのインポートなので、ネットワークを切った状態(--network none)で決定的に再現します。境界が Python 3.10 であることは、python:3.9-slim では同じ from collections import Mapping が DeprecationWarning(「3.10 で動かなくなる」と告げるもの)つきで動くことを確かめて裏づけています。エラー文言は実機出力から引用しています。移動した ABC の一覧については、機械検証の対象は Mapping の1点に限り、一般的な情報として Python 3.10 のリリースノート(collections からの ABC 削除)に沿って書いています。