ImportError: cannot import name <…> (most likely due to a circular import)

Question:

I have an issue with relative imports in python. (I really can’t do these imports the other way…)
Structure of my project is similar to this:


app
    ├───schemas
        └───__init__.py
        └───a.py
        └───b.py
        └───c.py
        └───d.py

In file a.py are classes A, ABase.
Files b.py, c.py, d.py are analogous.

init.py

from .a import A
from .b import B
from .c import C
from .d import D

The core of the issue is that I have to import classes A and B in both c.py and d.py file but I get "ImportError: cannot import name ‘D’ from partially initialized module ‘app.schemas.d’ (most likely due to a circular import) (.appschemas_init_.py)"

In files c.py and d.py I have tried already:

  1. from .a import A n from .b import B
  2. from ..schemas import A, B
  3. from . import A, B
    • some abominations of the above

For some reason, option 1 works in different projects and I have no idea why now it doesn’t…

EDIT: I have forgot about file d.py

Asked By: aremm

||

Answers:

Round Robin import or circular import only occurs when a imports b which imports a which etc.. I’m not sure why the above would cause this unless you’ve omitted something. However one thing you may be able to try is using the typing libraries TYPE_CHECK argument which is always False at runtime and True otherwise.

It’s usually used to get correct type hints while writing but could potentially fix your issue.

How you would do that is as follows:

from typing import TYPE_CHECKING
if TYPE_CHECKING:
    import a  # However you chose to import them
    import b

#everything else

I guess another way to handle it would be to check what modules are loaded and only load if it doesn’t exist.

All of these are crappy solutions, but without knowing exactly what you’ve written and where it’s complaining I can only guess that you’ve forgotten that a, b, or c are also importing d.

Answered By: TheLazyScripter
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.