'3 level chained python import is failing

I have the following folder structure across 3 levels: folder1 contains folder1_1 which again contains folder1_1_1. Now we have a .py file in each folder (besides the 'init.py' which is apparently needed, and sorry I don't know how to put those 2 lines before and after).

folder1  
L __init__.py  
L file1.py  
L folder1_1  
  L __init__.py  
  L file1_1.py  
  L folder1_1_1  
    L __init__.py  
    L file1_1_1.py

File contents file1.py

from folder1_1.file1_1 import Test1_1 as lvl2
class Test1:
    randomnumber = 1
    sum = randomnumber  + lvl2.sum
    print (sum)

file1_1.py

from folder1_1_1.file1_1_1 import Test1_1_1 as lvl3
class Test1_1:
    somenumber = 1
    sum = somenumber + lvl3.someothernumber
    print (sum)

file1_1_1.py

class Test1_1_1:
    someothernumber = 1

So each file imports from the directly lower folder. One step works: When I run file1_1.py the import from file1_1_1 works fine, and it produces the desired result (2)

But the '2 level' import in file1 fails:

  File "c:\Users\DSCO\Documents\folder1\folder1_1\file1_1.py", line 1, in <module>
    from folder1_1_1.file1_1_1 import Test1_1_1 as lvl3
ModuleNotFoundError: No module named 'folder1_1_1'

How can I import in this manner? Or do I need to rearrange my folders? In the actual code this structure is quite involved with file1_1 having many import statements pointing to file1_1_1 which is actually many files. Thats why the separate subfolder (folder1_1_1) I checked multiple S.O. issues but they are all somewhat different in my estimation.



Solution 1:[1]

PEP 366 may be of interest here, but you don't need the -m flag in this case. In your case, the only difference is the import within folder1_1/file1_1.py. I import starting from the entry name where it was run, so folder1_1 is included. You can also see more information in these answers:

The closest to your example that works is:

file tree

? tree
.
??? file1.py
??? folder1_1
    ??? __init__.py
    ??? file1_1.py
    ??? folder1_1_1
        ??? __init__.py
        ??? file1_1_1.py

file1.py

#!/usr/bin/env python3
from folder1_1.file1_1 import Test1_1 as lvl2


class Test1:
    randomnumber = 1
    sum = randomnumber + lvl2.sum
    print(sum)


if __name__ == "__main__":
    t1 = Test1()

folder1_1/file1_1.py

from folder1_1.folder1_1_1.file1_1_1 import Test1_1_1 as lvl3


class Test1_1:
    somenumber = 1
    sum = somenumber + lvl3.someothernumber
    print(sum)

folder1_1/folder1_1_1/file1_1_1.py

class Test1_1_1:
    someothernumber = 1
    print(someothernumber)

Now if you run from the top folder:

./file1.py

It yields the output:

1
2
3

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 theherk