ImportError: cannot import name from 'collections' in Python 3.10
Problem Statement
If you encounter the ImportError cannot import name 'Mapping' from 'collections' when running Python 3.10 or later, this is due to a breaking change in Python's standard library. The error typically occurs when trying to import abstract base classes (ABCs) like Mapping, MutableMapping, or Sequence directly from the collections module instead of the newer collections.abc submodule.
This error commonly affects:
- Outdated third-party packages that haven't been updated for Python 3.10+
- Legacy code that hasn't been modernized
- Projects using dependencies that haven't maintained compatibility
Root Cause
Python 3.3 introduced the collections.abc module as the proper location for abstract base classes, while keeping the old imports in collections for backward compatibility. However, starting with Python 3.10, importing these ABCs directly from collections was completely removed, resulting in the ImportError.
Earlier Python versions would show a deprecation warning:
Python 3.9.10
>>> from collections import Mapping
<stdin>:1: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated since Python 3.3, and in 3.10 it will stop workingSolutions
1. Update Your Dependencies
The most common and recommended solution is to update the problematic packages:
# Update a specific package
pip install <package-name> --upgrade
# Update all outdated packages
pip list --outdated --format=freeze | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 pip install -UCommon packages that may need updating include:
- Flask/Jinja2 (as shown in the original error)
- PyJWT
- Requests
- Other libraries that use collection ABCs
2. Manual Code Fix
If you control the code or need a temporary fix, update the import statements:
# Before (broken in Python 3.10+)
from collections import Mapping
from collections import MutableMapping
from collections import Sequence
# After (works in all versions)
from collections.abc import Mapping
from collections.abc import MutableMapping
from collections.abc import SequenceFor backward compatibility with older Python versions, use a try/except block:
try:
from collections.abc import Mapping
except ImportError:
from collections import MappingWARNING
Do not modify Python's standard library files (like collections/__init__.py) as suggested in some answers. This creates maintenance issues and may break other functionality.
3. Use a Compatible Python Version
If you cannot immediately update dependencies, consider using an older Python version:
# Using pyenv to manage multiple Python versions
pyenv install 3.9.18
pyenv local 3.9.18
# Using virtualenv with a specific Python version
virtualenv --python="/path/to/python3.9" "my_env"4. Environment Management with pipenv
If using pipenv, update your Pipfile to specify a compatible Python version:
# Remove existing environment
pipenv --rm
# Edit Pipfile to change python version
# [[source]]
# url = "https://pypi.org/simple"
# ...
# [requires]
# python_version = "3.9" # Change from "3.10"
# Recreate environment
pipenv shell
pipenv installPrevention and Best Practices
To avoid similar issues in the future:
- Keep dependencies updated: Regularly check for and apply updates to your dependencies
- Monitor deprecation warnings: Address warnings before they become errors
- Use dependency management tools: Tools like
pip-tools,poetry, orpipenvhelp maintain consistent environments - Test with upcoming Python versions: Use tools like
toxto test your code against multiple Python versions
TIP
When developing libraries or applications meant to support multiple Python versions, always use the collections.abc imports and include appropriate try/except blocks for maximum compatibility.
When to Use Each Solution
| Solution | Best For | Limitations |
|---|---|---|
| Update dependencies | Most cases, production environments | Requires compatible updated versions |
| Manual code fix | Temporary fixes, personal projects | Not sustainable for external dependencies |
| Older Python version | Legacy systems, urgent fixes | Misses out on newer Python features |
Most users will find that updating their dependencies (Solution 1) resolves the issue completely, as package maintainers have generally updated their code for Python 3.10+ compatibility.