Skip to content
Latchkey

Python "cannot import name X from partially initialized module" (circular) in CI

Python began importing a module, hit an import back to a module still mid-initialization, and the requested name was not defined yet. The interpreter labels the module "partially initialized" and points at a circular import.

What this error means

An import fails with "ImportError: cannot import name 'X' from partially initialized module 'Y' (most likely due to a circular import)". It reproduces deterministically based on import order.

python
ImportError: cannot import name 'User' from partially initialized module 'app.models'
(most likely due to a circular import) (/app/app/models/__init__.py)

Common causes

Two modules import each other at module scope

Module A imports B at the top, B imports A at the top; whichever loads first is incomplete when the other needs a name from it.

A package __init__ eagerly imports submodules that import back

An __init__.py that imports everything can create a cycle when a submodule imports a name from the package root.

How to fix it

Defer the import to call time

Move the cross-import inside the function that needs it so the module is fully loaded before the name is accessed.

app/services.py
def get_user():
    from app.models import User  # imported lazily to break the cycle
    return User.query.first()

Restructure to remove the cycle

  1. Identify the two modules that import each other from the traceback.
  2. Extract the shared name into a third module both can import.
  3. Re-run so neither module depends on the other at load time.

How to prevent it

  • Avoid module-level imports between two interdependent modules.
  • Keep package __init__.py files thin to avoid eager cycles.
  • Move shared types into a leaf module both sides import.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →