How to Fix : “ImportError: Cannot import name X” in Python

Introduction

The import error might occur in numerous cases and scenarios. Some classic examples of import error have been explained in the following tutorials:

In this article, you will learn about another import error that commonly occurs while you are dealing with packages and dependencies in Python.

💡A Quick Recap to Import Statement and ImportError:

In Python, the import statement serves two main purposes:

  • It is used to search for the module specified by its name, then load and initialize it if the module is required.
  • It additionally defines a name in the local namespace within the scope of the import statement. This local name would then be able to be used to reference the accessed module throughout the whole code.

If an import statement experiences difficulty in successfully importing a module, it raises an ImportError. Commonly, such an issue occurs because of a faulty installation or an invalid path, which will usually raise a ModuleNotFoundError in Python 3.6 and newer versions.

Problem Formulation

In Python “ImportError: cannot import name” error generally occurs when the imported class is not accessible, or the imported class is in a circular dependency. The following are the major reasons for the occurrence of “ImportError: cannot import name”:

  • The imported class is in a circular dependency.
  • The imported class is not available or has not been created.
  • The imported class has been misspelled.
  • The imported class from a specific module is misplaced.
  • The imported class is not present in the Python library. This generally happens while importing external libraries.

Example: Consider you have two modules: x.py and y.py, as shown below. These files represent how the ImportError occurs when there is a circular dependency between them, leading to a dead loop situation.

x.py

from x import x_1


def y_1():
    print('y1')
    x_1()


def y_2():
    print('y2')


if __name__ == '__main__':
    y_1()

y.py

from y import y_2


def x_1():
    print('x1')
    y_2()

Output:

ImportError: cannot import name 'x_1' from partially initialized module 'x' (most likely due to a circular import)

The error occurred because both the Python files, i.e., x and y, attempted to load each other simultaneously. The y module tried to load the x module while the x module attempted to load the y module. This created a circular load dependence leading to an error in the heap memory. To eliminate the ImportError, you have to get rid of the circular dependency.

Solution 1: Simply Use Import [Avoid from X import Y]

Simply put, the problem is occurring because we are trying to access the contents of one module from another simultaneously before the contents of the module are ready/initialized. This happens particularly because you are using: from x import x_1 and from y import y_2. Python can detect circular dependencies and prevent dead loops. Essentially what happens is that an empty placeholder is created for the module (i.e., it does not contain any content). After the modules that are circularly dependent are compiled, Python automatically updates the imported module. However, for Python to resolve the problem of circular dependency, you must use import x only instead of importing a particular content of the module with the help of the from statement. As you are no longer trying to load to the individual contents of the module at the top level, Python gets ample time to compile the module, thereby handling the circular dependency by itself.

Let’s have a look at the following code to understand how this works:

x.py

import x


def y_1():
    print('y1')
    x.x_1()


def y_2():
    print('y2')


if __name__ == '__main__':
    y_1()

y.py

import y


def x_1():
    print('x1')
    y.y_2()

Output:

y1
x1
y2

Solution 2: Re-Order Position Of Import Statement

In the above example, you can avoid the circular dependency by reformating the sequence of import statements. Thus, instead of importing the y module at the beginning within the x module, you can import it later, as shown in the following snippet:

x.py

def x_1():
    print('x1')
    y_2()


from y import y_2

Output:

y1
x1
y2

Conclusion

To sum things up, you can solve the “ImportError: Cannot import name X” Error by resolving the circular dependencies. You can do that either by eliminating the usage of from x import y form of importing contents from a module and simply using the import statement to import the entire module. Another workaround to this error is to change the position of the import statements accordingly within your code.

I hope this tutorial answered your queries. Please stay tuned and subscribe for more solutions and interesting discussions in the future. Happy coding!👨‍🎓


Recommended Course:

  • Do you want to master the most popular Python IDE fast?
  • This course will take you from beginner to expert in PyCharm in ~90 minutes.
  • For any software developer, it is crucial to master the IDE well, to write, test and debug high-quality code with little effort.
The Complete Guide to PyCharm
Join the PyCharm Masterclass now, and master PyCharm by tomorrow!