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.Mapping alias.
  • 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 collections ABCs moved to collections.abc; the old alias was removed in Python 3.10from collections import Mapping worked as a deprecated alias through Python 3.9, but was removed in Python 3.10, so it now raises ImportError. Import from collections.abc instead. The same move applies to Sequence, Iterable, Callable and the other abstract base classes.from collections import MappingPython 3.10+ImportError: cannot import name'Mapping' from 'collections'↓ Fixfrom collections.abc import MappingAlso moved to collections.abc (fix these too):Sequence · Iterable · Callable · MutableMapping · Set · Hashable · Sized
The collections ABCs moved to collections.abc; the old alias was removed in Python 3.10

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 Mapping

Confirm your version, since that's what changed:

import sys
print(sys.version_info)   # 3.10+ → the alias is gone

Is It Your Code or a Dependency?

Is the bad import in your code or a dependency? Read the traceback to decide the fixRead the traceback to see which file contains the failing import. If it is your own file, change it to import from collections.abc. If it is a library in site-packages, upgrade that package. If you cannot upgrade it, add a compatibility shim at startup before that library is imported.cannot import name 'Mapping' from 'collections'Read the traceback:your file or a library?your codeChange the import to:from collections.abc import Mappinga libraryCan you upgradethe package?yespip install -U<the package>noShim at startup,BEFORE importing it
Is the bad import in your code or a dependency? Read the traceback to decide the fix

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 (or dist-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, Iterable

Or 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 oldlib
⚠️

Don'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:

CategoryNames
MappingsMapping, MutableMapping
SequencesSequence, MutableSequence
SetsSet, MutableSet
IterationIterable, Iterator, Generator
ProtocolsCallable, Hashable, Sized, Container

Verification Steps

  1. python --version shows 3.10+ (confirming the cause).
  2. The failing import now reads from collections.abc import ... (your code), or the dependency is upgraded.
  3. pip show <package> reflects the newer version.
  4. The app imports cleanly — no ImportError at startup.
  5. 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, never collections.
  • 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

SymptomLikely causeFix
Import in your .py failsOld-style importfrom collections.abc import ...
Traceback points to site-packagesOutdated dependencypip install -U <package>
Fixed Mapping, now Sequence failsAll ABCs movedImport each from collections.abc
Upgrade doesn't fix itTransitive dependencyUpgrade the parent / pin fixed version
Package can't be upgradedAbandoned / constrainedShim before importing it
Works on 3.9, breaks on 3.10Alias removed in 3.10Fix imports, don't downgrade
Change vanished after reinstallEdited site-packagesUpgrade the package instead

External References

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.


Related Posts