DEV Community

Cover image for Why you should keep away from cyclic imports in Python
Deepjyoti Barman
Deepjyoti Barman

Posted on

Why you should keep away from cyclic imports in Python

Cyclic imports are something that every new programmer faces someday and spends a pretty good amount of time fixing whatever the bug, only to later find out it was a such a simple fix.

Let's first understand what cyclic imports are

Cyclic Imports

Let's take two different python files named test1.py and test2.py

# Test 1

import test2

def disp1():
    print("Test 1")

disp1()


Enter fullscreen mode Exit fullscreen mode

And

# Test 2

import test1

def disp2():
    print("Test 2")

disp2()


Enter fullscreen mode Exit fullscreen mode

Once that's done, let's try running one of the files.

It worked like a charm right.

For eg: If I run the test1.py file, I get the following output

Test 1
Test 2
Test 1
Enter fullscreen mode Exit fullscreen mode

The above output seems legit, however, let's make a small change to our code.

Let's import the functions particularly instead of the whole file.

# Test 1

from test2 import disp2

def disp1():
    print("Test 1")

disp1()
disp2()

Enter fullscreen mode Exit fullscreen mode

And

# Test 2

from test1 import disp1

def disp2():
    print("Test 2")

disp2()
disp1()

Enter fullscreen mode Exit fullscreen mode

Let's try running the test1.py file again.

Now, we get the following error

Traceback (most recent call last):
  File "test1.py", line 1, in <module>
    from test2 import disp2
  File "/home/deepjyoti30/Python/tempf/test2.py", line 1, in <module>
    from test1 import disp1
  File "/home/deepjyoti30/Python/tempf/test1.py", line 1, in <module>
    from test2 import disp2
ImportError: cannot import name 'disp2' from partially initialized module 'test2' (most likely due to a circular import) (/home/deepjyoti30/Python/tempf/test2.py)
Enter fullscreen mode Exit fullscreen mode

If you read the error properly, Python is suggesting we are doing a cyclic import.

Why?

So, when we called just the import test1, it was working fine but when we tried importing a particular function then it threw that error.

That is because, when we write an import statement, the whole file is not executed unlike when we write an from test import something which actually needs to make sure the file is executed so that the name we are importing exists.

It's as simple as that.

But in this example we just had two files with like 10 lines in each.
Let's consider this happening in a project of 1000's of lines where by mistake you made a cyclic import.

One cyclic import line like that can break the whole project and Python being Python, you might not even find the bug way until an user actually points it out (since it runs on an interpreter, duh).

This is why, we should be wary of making a cyclic import in a project by mistake.

I personally faced this way back when I was working on my first big python project and I have seen fellow developers not being able to fix this issue to the extent of actually adding help needed label in the GitHub issue.

So, be careful when you make imports in Python from now on ;-P

I also write on my personal page. Do check it out for my other posts. Cheers.

Top comments (0)