Home > Net >  cannot import name from partially initialized module
cannot import name from partially initialized module

Time:05-12

I have the following project and module setup:

enter image description here

class2.py:

from mod1.class1 import Class1


class Class2(object):
    def __init__(self, c1: Class1):
        self.c1 = c1

class2.py:

from mod2.class2 import Class2


class Class1(object):
    def __init__(self):
        self.c2 = Class2(self)

main.py:

from mod2.class2 import Class2

c2 = Class2()

The idea is that when a parent class initializing a child class, it introduces itself to the child class. This way the child class can call parent class methods.

This pattern works fine in strongly typed languages like C#.

When I run main.py, I get the following error:

Traceback (most recent call last):
  File "C:\Projects.Personal\exp02\main.py", line 2, in <module>
    from mod2.class2 import Class2
  File "C:\Projects.Personal\exp02\mod2\class2.py", line 2, in <module>
    from mod1.class1 import Class1
  File "C:\Projects.Personal\exp02\mod1\class1.py", line 1, in <module>
    from mod2.class2 import Class2
ImportError: cannot import name 'Class2' from partially initialized module 'mod2.class2' (most likely due to a circular import) (C:\Projects.Personal\exp02\mod2\class2.py)

Process finished with exit code 1

I just need to let Class2 know about the type of Class1.

Why am I getting such error?

What is the proper pattern to do this in Python?

Update #1

I understand that this is a circular import as it is specifically stated in the error message.

The idea explained in this article (https://stackabuse.com/python-circular-imports/) is not applicable here. Here I have Classes not module functions. I just need to annotate a variable. My code sample is very much simplified. The actual classes code is large. I don't want to combine them in one file.

IMO, This is a valid pattern and I can do it in Java or C#.

How can I implement the idea in Python?

CodePudding user response:

Use the TYPE_CHECKING flag from typing and make the class a string. At runtime TYPE_CHECKING is False so the import will not execute, but a type checker should find this acceptable.

from typing import TYPE_CHECKING
if TYPE_CHECKING:
    from mod1.class1 import Class1

class Class2(object):
    def __init__(self, c1: "Class1"):
        self.c1 = c1

CodePudding user response:

You have a circular import. Your Class1 and Class2 files are attempting to import each other- i'd suggest using one file that imports both classes.

  • Related