Fix ImportError: cannot import name 'Mapping' from 'collections'
Quick answer
ImportError: cannot import name 'Mapping' from 'collections' happens on Python 3.10+ because the abstract base classes were moved to collections.abc in Python 3.3 and the old collections alias was removed in 3.10. If the failing import is in your code, change it to from collections.abc import Mapping. Usually, though, it comes from an outdated dependency — read the traceback to see which library's file raised it, then upgrade that package with pip install -U.
You upgrade Python, run your app, and it dies at import time:
ImportError: cannot import name 'Mapping' from 'collections'Here's the part that trips people up: the offending line is usually not in your
code. It's buried in some dependency that hasn't been updated. Python moved the
abstract base classes like Mapping out of collections years ago, kept a
compatibility alias for a while, and finally removed it in Python 3.10. Any
old library still doing from collections import Mapping breaks the moment you run
it on 3.10 or newer.
This guide shows you how to tell whether it's your code or a dependency, fix each correctly, and — when you're stuck on a package that can't be upgraded — apply a safe shim.
Quick Answer
On Python 3.10+, from collections import Mapping raises this because the ABCs
moved to collections.abc (in Python 3.3) and the old alias was removed. If
it's your code, use from collections.abc import Mapping. If it's a
dependency (read the traceback), pip install -U <package> to a version
that already imports from collections.abc.
TL;DR
- Cause: Python 3.10 removed the
collections.Mappingalias. - Your code:
from collections.abc import Mapping. - A dependency (most common): read the traceback →
pip install -U <package>. - Same fix for
Sequence,Iterable,Callable,MutableMapping, etc. - Can't upgrade? Shim at startup, before importing the library.
- Downgrading Python is a stopgap, not a fix.
What Actually Changed
The abstract base classes (Mapping, Sequence, Iterable, Callable, and
friends) have lived in collections.abc since Python 3.3. For backward
compatibility, collections kept aliases pointing at them — but those aliases were
removed in Python 3.10. So:
# ❌ removed in Python 3.10+
from collections import Mapping
# ✅ the canonical location since Python 3.3
from collections.abc import MappingConfirm your version, since that's what changed:
import sys
print(sys.version_info) # 3.10+ → the alias is goneIs It Your Code or a Dependency?
Read the traceback bottom-up. The last frame shows the file that ran the bad import. Its path tells you everything:
File ".../site-packages/oldlib/utils.py", line 5, in <module>
from collections import Mapping
ImportError: cannot import name 'Mapping' from 'collections'- Path contains
site-packages(ordist-packages) → it's a dependency. - Path is your project directory → it's your code.
Fix A: It's your code
Change the import to point at collections.abc:
# ❌
from collections import Mapping, Sequence, Iterable
# ✅
from collections.abc import Mapping, Sequence, IterableOr import the module and qualify usage:
import collections.abc as abc
def is_mapping(x):
return isinstance(x, abc.Mapping)Fix B: It's a dependency (the common case)
Identify the package from the traceback path and upgrade it — a newer release
already imports from collections.abc:
# The traceback showed .../site-packages/oldlib/... → upgrade oldlib
pip install -U oldlib
# See what version you have and where it lives
pip show oldlibDon't hand-edit files under site-packages. It "works" until the next
reinstall wipes your change, and it breaks reproducible builds. Upgrade the
package (or pin a fixed version in requirements.txt) instead of patching
installed library code.
If pip install -U doesn't help, the fix may be in a transitive dependency —
upgrade the top-level package that pulls it in, or add a constraint for the fixed
version. Historically the usual suspects were old versions of packages that hadn't
kept up with the 3.10 change; a plain upgrade resolves almost all of them.
When You Can't Upgrade: The Shim
Sometimes a library is abandoned or pinned by another constraint. As a last resort, restore the aliases at startup — before the library is imported:
# put this at the very top of your entry point, before importing the old lib
import collections
import collections.abc
for _name in ("Mapping", "MutableMapping", "Sequence", "Iterable", "Callable"):
if not hasattr(collections, _name):
setattr(collections, _name, getattr(collections.abc, _name))
import oldlib # now its `from collections import Mapping` finds the alias- It must run before the offending import, or the library fails first.
- Add only the names the library actually needs.
- This is a bridge, not a destination — plan to upgrade or replace the package.
Downgrading to Python 3.9 also "fixes" it by bringing back the alias, but it's the worst option: you forfeit 3.10+ language features and security patches, and the underlying dependency is still broken. Prefer the upgrade or the shim.
The Full List of Moved Names
If you fix Mapping and immediately hit Sequence, that's expected — they all
moved. Import any of these from collections.abc:
| Category | Names |
|---|---|
| Mappings | Mapping, MutableMapping |
| Sequences | Sequence, MutableSequence |
| Sets | Set, MutableSet |
| Iteration | Iterable, Iterator, Generator |
| Protocols | Callable, Hashable, Sized, Container |
Verification Steps
python --versionshows 3.10+ (confirming the cause).- The failing import now reads
from collections.abc import ...(your code), or the dependency is upgraded. pip show <package>reflects the newer version.- The app imports cleanly — no
ImportErrorat startup. python -c "import collections.abc; print(collections.abc.Mapping)"works (it always should — that's the canonical home).
Green state: every ABC import points at collections.abc, all dependencies are
on versions that do the same, and the app starts with no import errors.
Prevention
- Import ABCs from
collections.abc, nevercollections. - Keep dependencies current; test on the Python version you deploy on.
- Run your test suite on new Python versions before upgrading in production.
- Pin fixed versions of packages known to have lagged the 3.10 change.
- Prefer upgrading over shimming; treat shims as temporary.
- Never edit installed library code under
site-packages.
Troubleshooting Matrix
| Symptom | Likely cause | Fix |
|---|---|---|
Import in your .py fails | Old-style import | from collections.abc import ... |
Traceback points to site-packages | Outdated dependency | pip install -U <package> |
Fixed Mapping, now Sequence fails | All ABCs moved | Import each from collections.abc |
| Upgrade doesn't fix it | Transitive dependency | Upgrade the parent / pin fixed version |
| Package can't be upgraded | Abandoned / constrained | Shim before importing it |
| Works on 3.9, breaks on 3.10 | Alias removed in 3.10 | Fix imports, don't downgrade |
| Change vanished after reinstall | Edited site-packages | Upgrade the package instead |
Related Guides
- Fix AttributeError: 'DataFrame' object has no attribute 'append' after Pandas 2.0
- Fix ModuleNotFoundError: No module named 'dotenv'
- Fix ValueError: too many values to unpack (expected 2)
- Resolve ModuleNotFoundError: No module named 'cv2'
- Upgrading a project to a new Python version safely
External References
- Python — collections.abc
- Python 3.10 — What's new (removed aliases)
- Python — collections module
- pip — Installing and upgrading packages
FAQs
Why did Python keep the alias for so long then remove it?
The move happened in 3.3, with a DeprecationWarning on the collections alias
for years, and finally a hard removal in 3.10. The long runway was to give
libraries time to migrate — most did, which is why an upgrade usually fixes it.
How do I know which package to upgrade?
The traceback's last frame shows a file path under site-packages. The directory
right after site-packages is the package name. pip show <name> confirms it and
shows the installed version and location.
Is collections.abc available on old Python too?
Yes — since 3.3. That's why from collections.abc import Mapping is safe across
all supported versions, while from collections import Mapping only worked up to
3.9. Always import from collections.abc.
Can this happen with Callable or Iterable specifically?
Yes — they moved with the rest. If a library imports several ABCs from
collections, you may see the error for whichever it hits first. Upgrading the
library fixes all of them at once.
Does this affect OrderedDict or defaultdict?
No. Those are concrete classes that still live in collections. Only the
abstract base classes moved to collections.abc. from collections import OrderedDict still works fine.
Key takeaways
- •Python 3.10 removed the collections.Mapping alias — the ABCs live in collections.abc since 3.3.
- •In your own code, change from collections import Mapping to from collections.abc import Mapping.
- •Most often it's an outdated dependency, not your code — read the traceback to find the library.
- •Upgrade the offending package with pip install -U <package> once the traceback names it.
- •The same move applies to Sequence, Iterable, Callable, MutableMapping and other ABCs.
- •If you truly can't upgrade the library, add a compatibility shim at startup before importing it.
Frequently asked questions
Why can't I import Mapping from collections anymore?
Because Python 3.10 removed the backward-compatibility alias. The abstract base classes moved to collections.abc in Python 3.3, and collections kept an alias until 3.9. On Python 3.10+, from collections import Mapping raises ImportError. Import from collections.abc instead.
How do I fix cannot import name 'Mapping' from 'collections'?
If the import is in your code, change it to from collections.abc import Mapping. If the traceback points into a library under site-packages, that dependency is outdated — upgrade it with pip install -U <package>. Read the traceback's file path to identify which one.
The error comes from a library I didn't write — what do I do?
Find the package from the traceback's file path (it's under site-packages), then upgrade it: pip install -U <package>. A newer version imports from collections.abc. If no fixed release exists and you can't switch libraries, add a shim at startup before importing it.
Which classes moved from collections to collections.abc?
The abstract base classes: Mapping, MutableMapping, Sequence, MutableSequence, Set, MutableSet, Iterable, Iterator, Callable, Hashable, Container, Sized, and more. All of them must be imported from collections.abc on Python 3.10+; the collections aliases are gone.
How do I add a compatibility shim for an old dependency?
At the very top of your entry point, before importing the library, run: import collections, collections.abc; then for each needed name, collections.Mapping = collections.abc.Mapping. This restores the old alias. Use it only as a last resort when you cannot upgrade or replace the package.
Should I downgrade Python to fix this?
Only as a temporary stopgap. Pinning Python 3.9 restores the alias, but you lose 3.10+ features and security updates, and you'll still need to migrate later. Upgrading the outdated dependency (or fixing your import) is the correct long-term fix.