← Debugging Guides

阅读中文版本

Python ImportError: cannot import name X from Y

Fix ImportError: cannot import name when a symbol is missing, circular imports bite, or a local file shadows the installed package.

intermediatedebuggingpythonimports

Symptoms

  • ImportError: cannot import name X from Y
  • The import works at the top level but fails when the module is imported by another
  • It broke after renaming a function or moving code

Possible causes

  • The symbol was renamed or removed in the installed version
  • A circular import leaves the module partially initialised
  • A local file shadows the package being imported
  • The symbol is defined after the import statement inside a module that runs it

Diagnosis steps

Verify the symbol exists

python -c "import Y; print(hasattr(Y, 'X'))"

Interpretation

If hasattr is False, the name is simply absent in this version.

Check where Y loads from

python -c "import Y; print(Y.__file__)"

Interpretation

A path inside your project means shadowing, not a real package.

Look for circular dependency loops

Interpretation

If Y imports the module that imports Y, one side sees a half-built module during import.

Root cause

ImportError for a name means the target module exists but does not expose that attribute at import time. This happens when the symbol is absent in the installed version, when a circular import returns a partially initialised module, or when a local module shadows the intended package.

Fix

Import the symbol from its real location, lazy-import inside functions to break cycles, and move imports to the top of modules. Rename shadowing files and clear __pycache__. When a symbol moved, update to the new name or pin the dependency to the version that still exports it.

Verify the fix

Re-import the module and confirm the symbol resolves without error, then run the affected entry point to prove the whole chain works.

Symptoms

An import statement fails with cannot import name X from Y, even though the package installs fine. It frequently appears only in larger applications where modules import each other.

Diagnosis

Check the symbol and the module origin:

import Y
print(Y.__file__)
print(hasattr(Y, 'X'))

If __file__ is inside your tree, you are importing a local file. Otherwise a circular import can return a module that has not finished defining X.

Fix

Break cycles with local imports:

# a.py imports b.py, b.py imports a.py -> cycle
def handler():
    from a import helper   # deferred, avoids the cycle
    return helper()

Rename shadowing files and update renamed symbols.

Verification

Run python -c "from Y import X"; it should succeed, and the application entry point should start without the ImportError.

Additional Notes

The name may exist yet not be importable because of a circular dependency, where the importing module runs before the imported one finishes defining the symbol. That is why the same import works from a script but fails inside a package that forms a cycle. Deferring the import into the function that needs it, or moving shared definitions into a lower-level module that neither side imports, breaks the cycle cleanly. Distinguishing a truly missing symbol from a partially initialised module matters, since the fixes are entirely different.