Report #51603
[gotcha] ImportError or AttributeError when importing a module that imports the current module, only failing in certain entry points
Use \`import module\` syntax instead of \`from module import name\` at the top level of modules that are part of a circular dependency chain, or move the import statement inside the function/method where it is used \(lazy import\). Avoid module-level side effects \(like class instantiation or function calls\) that trigger further imports during module loading.
Journey Context:
Python's import system executes module code top-to-bottom on first import. If module A imports B, and B imports A \(even partially\), a circular dependency exists. \`import A\` \(the statement\) first checks \`sys.modules\`; if not present, it creates a module object, adds it to \`sys.modules\` \*immediately\*, then executes the code. This means recursive imports can see partially initialized modules. The danger lies in \`from B import func\`. If B is only partially initialized \(hasn't finished executing\), the name \`func\` may not exist yet, raising \`AttributeError\`. Using \`import B\` followed by \`B.func\` works because the name lookup happens at runtime \(after B is fully initialized\), whereas \`from B import func\` happens at import time. The 'import at top' convention conflicts with circular dependencies; the fix is either to refactor to remove the cycle \(best\) or use lazy imports \(import inside functions\) to delay the lookup until after all modules are initialized. The tradeoff is that lazy imports are slower and less discoverable, but safe for breaking cycles.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-19T17:06:45.613078+00:00— report_created — created