152

I'm getting this error

Traceback (most recent call last):
  File "/Users/alex/dev/runswift/utils/sim2014/simulator.py", line 3, in <module>
    from world import World
  File "/Users/alex/dev/runswift/utils/sim2014/world.py", line 2, in <module>
    from entities.field import Field
  File "/Users/alex/dev/runswift/utils/sim2014/entities/field.py", line 2, in <module>
    from entities.goal import Goal
  File "/Users/alex/dev/runswift/utils/sim2014/entities/goal.py", line 2, in <module>
    from entities.post import Post
  File "/Users/alex/dev/runswift/utils/sim2014/entities/post.py", line 4, in <module>
    from physics import PostBody
  File "/Users/alex/dev/runswift/utils/sim2014/physics.py", line 21, in <module>
    from entities.post import Post
ImportError: cannot import name Post

and you can see that I use the same import statement further up and it works. Is there some unwritten rule about circular importing? How do I use the same class further down the call stack?


See also What happens when using mutual or circular (cyclic) imports in Python? for a general overview of what is allowed and what causes a problem WRT circular imports. See What can I do about "ImportError: Cannot import name X" or "AttributeError: ... (most likely due to a circular import)"? for techniques for resolving and avoiding circular dependencies.

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
CpILL
  • 6,169
  • 5
  • 38
  • 37

8 Answers8

249

I think the answer by jpmc26, while by no means wrong, comes down too heavily on circular imports. They can work just fine, if you set them up correctly.

The easiest way to do so is to use import my_module syntax, rather than from my_module import some_object. The former will almost always work, even if my_module included imports us back. The latter only works if my_object is already defined in my_module, which in a circular import may not be the case.

To be specific to your case: Try changing entities/post.py to do import physics and then refer to physics.PostBody rather than just PostBody directly. Similarly, change physics.py to do import entities.post and then use entities.post.Post rather than just Post.

Neuron
  • 5,141
  • 5
  • 38
  • 59
Blckknght
  • 100,903
  • 11
  • 120
  • 169
  • 11
    Is this answer compatible with relative imports? – Joe Dec 30 '14 at 21:45
  • 40
    Why does this happen? – Juan Pablo Santos Jul 21 '15 at 19:19
  • 16
    It's wrong to say that non-`from` syntax will always work. If I have `class A(object): pass; class C(b.B): pass` in module a and `class B(a.A): pass` in module b then circular import is still a problem and this won't work. – CrazyCasta Jul 30 '15 at 03:46
  • 2
    You're right, any circular dependencies in the modules' top level code (such as the base classes of class declarations in your example) will be a problem. That is the sort of situation where jpmc's answer that you should refactor the module organization is probably 100% correct. Either move class `B` into module `a`, or move class `C` into module `b` so you can break the cycle. It's also worth noting that even if only one direction of the circle has top-level code involved (e.g. if class `C` didn't exist), you *might* get an error, depending on which module got imported first by other code. – Blckknght Jul 30 '15 at 07:08
  • @Joe, no, this doesn't work for relative imports since module importation must be absolute. – Tyler Crompton May 06 '16 at 01:44
  • 3
    @TylerCrompton: I'm not sure what you mean by "module importation must be absolute". Circular relative imports can work, as long as you're importing modules, not their contents (e.g. `from . import sibling_module`, not `from .sibling_module import SomeClass`). There's some more subtlety when a package's `__init__.py` file is involved in the circular import, but the issue is both rare, and probably a bug in the `import` implementation. See [Python bug 23447](http://bugs.python.org/issue23447), which I submitted a patch for (which alas has been languishing). – Blckknght May 06 '16 at 01:48
  • Module importation is just my way of saying “`import` statements of the form `import module`”, which are required to be absolute. Anyway, I've found that my “\_\_init\_\_.py” imports an object `B` from a sibling module that imports the object `A` (because BBB is a subclass of `A`) from “\_\_init\_\_.py” and `A` uses `B`. I guess I'll have to refactor my code. :/ – Tyler Crompton May 06 '16 at 03:58
  • 1
    Yeah, I suppose I should also qualify my remark a bit too: circular relative imports will usually work in Python 3.5 (the main exception is `from . import *`). Earlier Python versions may have more issues. – Blckknght May 06 '16 at 04:01
  • I have revised the section decrying circular imports to better explain my intent. (My conclusion that they are not to be used has not changed.) It may or may not change your answer, but I thought I'd notify you in case you want to update your response. – jpmc26 Mar 18 '17 at 23:16
  • 1
    Circular imports are usually (but not always) evidence of poor design or need for refactor. – meawoppl Jun 16 '17 at 00:03
  • 1
    this is one of the 'it works...why?' moment. But thanks for sharing the solution, it's effective! – Suicide Bunny Jul 16 '18 at 19:27
  • Works as a charm. – Vadim Oct 14 '20 at 12:53
  • If you take type annotations into account, your answer is not so valid anymore because then you'll have a lot of top level references to types imported from other modules. – Damian Birchler Nov 26 '21 at 21:09
  • @DamianBirchler: You're right that type hinting tends to proliferate top-level references to types, though the Python developers, with PEPs 563 and 649, are looking to improve the situation by deferring when annotations get evaluated. – Blckknght Nov 26 '21 at 22:41
  • This **only** resolves the problem if there is **no top-level code** trying to access an attribute of the partially-uninitialized module. Gene Olson's answer explains why. – Karl Knechtel Aug 11 '22 at 03:53
70

When you import a module (or a member of it) for the first time, the code inside the module is executed sequentially like any other code; e.g., it is not treated any differently that the body of a function. An import is just a command like any other (assignment, a function call, def, class). Assuming your imports occur at the top of the script, then here's what's happening:

  • When you try to import World from world, the world script gets executed.
  • The world script imports Field, which causes the entities.field script to get executed.
  • This process continues until you reach the entities.post script because you tried to import Post
  • The entities.post script causes physics module to be executed because it tries to import PostBody
  • Finally, physics tries to import Post from entities.post
  • I'm not sure whether the entities.post module exists in memory yet, but it really doesn't matter. Either the module is not in memory, or the module doesn't yet have a Post member because it hasn't finished executing to define Post
  • Either way, an error occurs because Post is not there to be imported

So no, it's not "working further up in the call stack". This is a stack trace of where the error occurred, which means it errored out trying to import Post in that class. You shouldn't use circular imports. At best, it has negligible benefit (typically, no benefit), and it causes problems like this. It burdens any developer maintaining it, forcing them to walk on egg shells to avoid breaking it. Refactor your module organization.

jpmc26
  • 28,463
  • 14
  • 94
  • 146
  • yeah, i thought it was something like that. Its just a class definition in that file and i just need to import so I can make a class check i.e. `if userData == Post:` :-? – CpILL Mar 05 '14 at 02:51
  • 1
    Should be `isinstance(userData, Post)`. Regardless, you don't have a choice. The circular import won't work. The fact you have circular imports is a code smell to me. It suggests you have some functionality that should be moved out to a third module. I couldn't say what without looking at both entire classes. – jpmc26 Mar 05 '14 at 02:53
  • 5
    @CpILL After a while, a very hacky option did occur to me. If you can't get around doing this for now (due to time constraints or what have you), then you *could* do your import locally inside the method where you're using it. A function body inside `def` is not executed until the function is called, so the import wouldn't occur until you actually called the function. By then, the `import`s should work since one of the modules would have completely imported prior to the call. That is an absolutely disgusting hack, and it should not remain in your code base for any significant length of time. – jpmc26 Mar 05 '14 at 20:30
  • 17
    I think your answer comes down too hard on circular imports. Circularly imports usually work if you do just `import foo` rather than `from foo import Bar`. That's because most modules just define stuff (like functions and classes) that runs later. Modules that do significant things when you import them (like a script not protected by `if __name__ == "__main__"`) might still be trouble, but that's not too common. – Blckknght Mar 05 '14 at 22:33
  • 9
    @Blckknght I think that you are setting yourself up for spending time on weird problems that other people will have to investigate and be confused by if you use circular imports. They force you to spend time being careful not to trip over them, and on top of that are a code smell that your design needs refactoring. I might have been wrong about whether they're technically feasible, but they're a terrible design choice destined to cause problems sooner or later. Clarity and simplicity are holy grails in programming, and circular imports violate both in my book. – jpmc26 Mar 12 '14 at 23:39
  • @jpmc26: You're right that circular imports can be complicated and confusing, while a one-directional import setup is likely to be simpler. However, many situations where circular imports come up are not really that complicated at all (e.g. the modules only contain function and class definitions at the top level, nothing that else that runs at module-load time). All of those modules will just work if you use `import module` syntax rather than `from module import something`. That's likely to be easier to learn and understand than dependency injection or any other kind of workaround. – Blckknght Mar 13 '14 at 00:31
  • 1
    @Blckknght You don't need a work around. Group functions and classes that should be together in the same modules, and if you still have circular imports, you probably have too much functionality in one module and it should be split up. In the absolute worst case, you split something into 2 modules when maybe it could have been one from some intuitive perspective. Simple and clean code concerns override that "intuitive" thinking. (Really, I would argue that our intuition should be more tuned to simple and clean code concerns than to whatever other kind of intuition is involved, anyway.) – jpmc26 Mar 13 '14 at 01:01
  • 8
    Alternatively; you have split up your functionality too much and that is the cause of the circular imports. If you have two things that rely on each other *all the time*; it may be best to just put them in one file. Python is not Java; no reason to not group functionality/classes into a single file to prevent weird import logic. :-) – Mark Mar 16 '15 at 18:34
  • Being dynamically typed, Python should be able to have "placeholder" memory definitions for the first module before the second module asks for it, similarly to C++ forward declarations. – Dagrooms May 07 '18 at 17:23
  • @Dagrooms It can, if you import only the module and don't reference any members of it before the module finishes executing. That doesn't mean it's a good design choice. – jpmc26 May 07 '18 at 19:56
  • @jpmc26 firstly I don't think you understand my comment, and secondly there are much worse design choices built into python as it is. – Dagrooms May 08 '18 at 21:08
64

To understand circular dependencies, you need to remember that Python is essentially a scripting language. Execution of statements outside methods occurs at compile time. Import statements are executed just like method calls, and to understand them you should think about them like method calls.

When you do an import, what happens depends on whether the file you are importing already exists in the module table. If it does, Python uses whatever is currently in the symbol table. If not, Python begins reading the module file, compiling/executing/importing whatever it finds there. Symbols referenced at compile time are found or not, depending on whether they have been seen, or are yet to be seen by the compiler.

Imagine you have two source files:

File X.py

def X1:
    return "x1"

from Y import Y2

def X2:
    return "x2"

File Y.py

def Y1:
    return "y1"

from X import X1

def Y2:
    return "y2"

Now suppose you compile file X.py. The compiler begins by defining the method X1, and then hits the import statement in X.py. This causes the compiler to pause compilation of X.py and begin compiling Y.py. Shortly thereafter the compiler hits the import statement in Y.py. Since X.py is already in the module table, Python uses the existing incomplete X.py symbol table to satisfy any references requested. Any symbols appearing before the import statement in X.py are now in the symbol table, but any symbols after are not. Since X1 now appears before the import statement, it is successfully imported. Python then resumes compiling Y.py. In doing so it defines Y2 and finishes compiling Y.py. It then resumes compilation of X.py, and finds Y2 in the Y.py symbol table. Compilation eventually completes w/o error.

Something very different happens if you attempt to compile Y.py from the command line. While compiling Y.py, the compiler hits the import statement before it defines Y2. Then it starts compiling X.py. Soon it hits the import statement in X.py that requires Y2. But Y2 is undefined, so the compile fails.

Please note that if you modify X.py to import Y1, the compile will always succeed, no matter which file you compile. However if you modify file Y.py to import symbol X2, neither file will compile.

Any time when module X, or any module imported by X might import the current module, do NOT use:

from X import Y

Any time you think there may be a circular import you should also avoid compile time references to variables in other modules. Consider the innocent looking code:

import X
z = X.Y

Suppose module X imports this module before this module imports X. Further suppose Y is defined in X after the import statement. Then Y will not be defined when this module is imported, and you will get a compile error. If this module imports Y first, you can get away with it. But when one of your co-workers innocently changes the order of definitions in a third module, the code will break.

In some cases you can resolve circular dependencies by moving an import statement down below symbol definitions needed by other modules. In the examples above, definitions before the import statement never fail. Definitions after the import statement sometimes fail, depending on the order of compilation. You can even put import statements at the end of a file, so long as none of the imported symbols are needed at compile time.

Note that moving import statements down in a module obscures what you are doing. Compensate for this with a comment at the top of your module something like the following:

#import X   (actual import moved down to avoid circular dependency)

In general this is a bad practice, but sometimes it is difficult to avoid.

Gene Olson
  • 890
  • 6
  • 4
  • 3
    I don't think there is compiler or compile time in python at all – Mia Jul 08 '17 at 13:17
  • 8
    Python *does* have a compiler, and *is* compiled @pkqxdd , compilation is just usually hidden away from the user. This might be a little confusing, but it would be difficult for the author to give this admirably clear description of what's going on without some reference to Python's, somewhat obscured, "compile time". – Hank Oct 31 '17 at 19:48
  • @pkqxdd https://nedbatchelder.com/blog/201803/is_python_interpreted_or_compiled_yes.html – jpmc26 Aug 21 '19 at 20:42
  • 2
    I went ahead to try this on my machine and got a different result. Ran X.py but got error "cannot import name 'Y2' from 'Y' ". Ran Y.py with no problem though. I am on Python 3.7.5 could you help to explain what is the issue here? – xuefeng huang Jan 08 '20 at 10:52
  • This answer matched my intuition, but I see the same error as @xuefenghuang, on Python 3.9.6. Is the current behavior maybe a bit stricter, ie you can circularly import a partially initialized module, but not a specific name from a partially initialized module? – ryan Aug 09 '21 at 17:32
  • I think the different errors being described in the comments are due to executing one or the other file as a script. A script gets run as a module named `__main__`, not as its own module name. So if you run `X.py` as `__main__`, it will import `Y` which will import `X` (which will be a copy of `__main__`, but without the parts that have already been initialized). If you wrote a separate script that either imported `X` or `Y`, you'd see the behavior described in the question (importing `X` first will work, importing `Y` first will fail). – Blckknght Sep 24 '21 at 21:22
  • Briefly, "compile time" is the time when `SyntaxError` can occur. – Karl Knechtel Apr 25 '23 at 14:52
24

For those of you who, like me, come to this issue from Django, you should know that the docs provide a solution: https://docs.djangoproject.com/en/1.10/ref/models/fields/#foreignkey

"...To refer to models defined in another application, you can explicitly specify a model with the full application label. For example, if the Manufacturer model above is defined in another application called production, you’d need to use:

class Car(models.Model):
    manufacturer = models.ForeignKey(
        'production.Manufacturer',
        on_delete=models.CASCADE,
)

This sort of reference can be useful when resolving circular import dependencies between two applications...."

Malik A. Rumi
  • 1,855
  • 4
  • 25
  • 36
10

I was able to import the module within the function (only) that would require the objects from this module:

def my_func():
    import Foo
    foo_instance = Foo()
Alex S.
  • 974
  • 1
  • 13
  • 18
6

If you run into this issue in a fairly complex app it can be cumbersome to refactor all your imports. PyCharm offers a quickfix for this that will automatically change all usage of the imported symbols as well.

enter image description here

Andreas Bergström
  • 13,891
  • 5
  • 59
  • 53
2

According to this answer we can import another module's object in the block( like function/ method and etc), without circular import error occurring, for example for import Simple object of another.py module, you can use this:

def get_simple_obj():
    from another import Simple
    return Simple

class Example(get_simple_obj()):
    pass

class NotCircularImportError:
    pass

In this situation, another.py module can easily import NotCircularImportError, without any problem.

  • 1
    I wouldn't say "easily". This would become a mess quickly as you needed more and more modules imported. Its also not very pythonic. But if your in a pinch... – CpILL Mar 07 '22 at 07:37
1

I was using the following:

from module import Foo

foo_instance = Foo()

but to get rid of circular reference I did the following and it worked:

import module.foo

foo_instance = foo.Foo()
Khuram
  • 1,820
  • 1
  • 26
  • 33
  • Answers like this belong at https://stackoverflow.com/questions/744373 instead, and the material is already very well covered there. – Karl Knechtel Apr 25 '23 at 14:56