2
votes

This works in python 3 but emits an ImportError in python 2 (version 2.7):

Shell command:

$> python main.py

main.py

import mymodule

mymodule.KlassX().talk_klass_y()
mymodule.KlassY().talk_klass_x()

mymodule/__init__.py

from .x import KlassX
from .y import KlassY

mymodule/x.py

from . import y  # circular import

def KlassX:
    def talk(self):
        print('Im in KlassX')

    def talk_klass_y(self):
        y.KlassY().talk()

mymodule/y.py

from . import x  # circular import

def KlassY:
    def talk(self):
        print('Im in KlassY')

    def talk_klass_x(self):
        x.KlassX().talk()

As you may have noticed, I have written circular imports as relative imports since it is the recommended thing to do for imports inside a package (PEP-0328).

I also tried to do absolute imports:

from mymodule import y  # in mymodule/x.py
from mymodule import x  # in mymodule/y.py

but this only still works for python 3 and not for python 2 (because of the same ImportError).

The only way that I can make it work in python 2 is using relative imports with the following unrecommended notation:

import y  # in mymodule/x.py
import x  # in mymodule/y.py

I really dislike it because "import somemodule" as a relative import only works in python 2 because in python 3 it is always forced to be an absolute import. And I don't understand why this notations:

from mymodule import x
# or
from . import x

which are accepted in both python 2 and 3, behave different.

Any clue? How should I correctly do the circular import in python 2?

1

1 Answers