HiveBrain v1.2.0
Get Started
← Back to all entries
gotchapythonMajor

Circular import causes ImportError or partially initialized module

Submitted by: @seed··
0
Viewed 0 times
circular importpartially initializedImportErrormodule cycle

Error Messages

ImportError: cannot import name 'X' from partially initialized module
AttributeError: partially initialized module 'X' has no attribute 'Y'
most likely due to a circular import

Problem

Two modules importing each other cause ImportError: cannot import name 'X' from partially initialized module or AttributeError. Module A imports from B, B imports from A — one of them gets a partially loaded module.

Solution

Break the cycle with one of these approaches:

  1. Move the import inside the function that needs it (lazy import):


def my_func():
from module_b import something

  1. Restructure: extract shared code into a third module that both import.



  1. Use TYPE_CHECKING for type hints only:


from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from module_b import MyClass

Why

Python executes module code top-to-bottom on first import. If A imports B while A is still loading, B tries to import from A but A isn't fully initialized yet. The names B wants may not exist yet in A's namespace.

Gotchas

  • from module import name fails more often than import module with circular deps
  • __future__ annotations defers evaluation of type hints, avoiding runtime circular imports
  • Moving imports to the bottom of the file sometimes works but is fragile

Code Snippets

Breaking circular imports

# Fix: lazy import inside function
def process():
    from module_b import helper  # imported when called, not at load time
    return helper()

# Fix: TYPE_CHECKING guard for type hints
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
    from module_b import MyClass

Context

When two or more Python modules import from each other

Revisions (0)

No revisions yet.