MPKenning
MPKenning

Reputation: 569

Why does this non-circular inheritance in Python trigger an import error?

EDIT: Turns out the inheritance is circular. Read on!

I am using Python 3.6. I tried to produce a minimal code sample to debug an import error I was having in a code project which was caused by the way I have set up inheritance. I suspect that I have done something wrong, but I don't understand what principle of coding I have violated.

The file structure looks like this:

temp
 |-- __init__.py
 |-- superclass_file.py
 |-- subclass_file.py 
 |-- tests
      |-- __init__.py
      |-- test_subclass_file.py

These are the contents of the Python scripts:

# temp/__init__.py

from .subclass_file import *
from .superclass_file import *
# temp/superclass_file.py

class Parent:

    def __init__(self):
        print('I exist.')
# temp/subclass_file.py

from temp import Parent


class Child(Parent):

    def __init__(self):
        super().__init__()
        print('And I exist because of it.')

    def print_something(self):
        print('Yes, I\'m here.')


if __name__ == '__main__':
    Child()
# temp/tests/__init__.py

from .test_subclass_file import *
# temp/tests/test_subclass_file.py

from unittest import TestCase

from temp import Child


class TestChild(TestCase):

    def check_inheritance(self):
        c = Child()

        c.print_something()

When I run check_inheritance(), it fails and throws this error:

/usr/local/bin/python3.6 ~/temp/subclass_file.py
Traceback (most recent call last):
  File "~/temp/subclass_file.py", line 1, in <module>
    from temp import Parent
  File "~/temp/__init__.py", line 1, in <module>
    from .subclass_file import *
  File "~/temp/subclass_file.py", line 1, in <module>
    from temp import Parent
ImportError: cannot import name 'Parent'

I obtain a similar error when I run the main() method in subclass_file.py.

However, the error disappears completely when I change the import of Parent in subclass_file.py from from temp import Parent to from temp.superclass_file import Parent.

Why does this happen? Why can't I use the same import signature I would use anywhere else—from temp import Parent—in the case of inheritance? Have I configured the __init__.py file incorrectly?

Upvotes: 1

Views: 61

Answers (1)

Ankirama
Ankirama

Reputation: 498

Right now you are importing subclass_file.py before superclass_file.py.

So when you try to do from temp import Parent, because subclass_file.py was imported before, it doesn't know what Parent is. Furthermore, you may create a circular import issue.

The best way should be to use from temp.superclass_file import Parent

If you really want / need to use the other way, then you must import superclass_file.py before subclass_file.py

Upvotes: 1

Related Questions