PythonMastery
reference 3 min read · lesson 25 of 60 in Errors

ImportError: cannot import name 'X' from 'Y'

1 · The lesson

read

What this error means

Python found and successfully imported module Y, but when it tried to bind the name X from inside Y, that name was not there. Either X does not exist in Y (a typo, or it was renamed or removed in this version), or Y is in the middle of importing and X has not been defined yet. The second case is a circular import.

When you see it

text
Traceback (most recent call last):
  File "app.py", line 1, in <module>
    from collections import OrderedDic
ImportError: cannot import name 'OrderedDic' from 'collections'

Newer Python versions also tell you where they looked:

text
ImportError: cannot import name 'soft_unicode' from 'markupsafe'
(/usr/lib/python3/site-packages/markupsafe/__init__.py)

Why it happens

Cause 1: a typo or wrong case. OrderedDic instead of OrderedDict, Path from os instead of pathlib.

Cause 2: a version mismatch. The name exists in an older or newer version of the package than the one you have installed. markupsafe.soft_unicode was removed in MarkupSafe 2.1, but old Jinja2 versions (2.x) still import it.

Cause 3: a circular import. Module A imports from B at the top, and B imports from A at the top. The module that Python started loading first is only half-loaded when the other one tries to read from it.

python · run on your machine
# a.py
from b import helper
def thing(): return helper() + 1

# b.py
from a import thing            # fails: a is only half imported and has no `thing` yet
def helper(): return 0

How to fix it

For typos. Check the docs or use dir(Y):

python
import collections
print([n for n in dir(collections) if 'dict' in n.lower()])

For version mismatches. Check what's installed and pin compatible versions:

bash
python -m pip show markupsafe jinja2
python -m pip install "markupsafe<2.1"   # or upgrade jinja2 instead

For circular imports. There are three reliable fixes. The cleanest one is first.

1. Move the shared code into a third module. Both A and B import from common.py, and there is no cycle.

2. Move the import inside the function that needs it. The import then runs only when the function is called, and by then both modules are fully loaded.

python # a.py def thing(): from b import helper return helper() + 1

3. Import the module, not the name. Write import b, then call b.helper(). Python looks up b.helper only when that line runs, so a half-loaded module causes fewer problems than with from b import helper, which needs the name at import time.

When you'd see this in real code

  • You upgrade a dependency (Django, Flask, SQLAlchemy), and a third-party plugin written for the older API breaks.
  • Two modules in your own project that both reference each other's models or schemas.
  • Copying an import from a code sample written for a newer version of the library.
  • ModuleNotFoundError: No module named 'Y': Y itself can't be found. See error-modulenotfounderror.
  • AttributeError: module 'Y' has no attribute 'X': the same root cause as this ImportError, but caused by Y.X instead of from Y import X.

See Also

Found this useful? Share it with a friend who’s learning Python.