ValueError: attempted relative import beyond top-level package - part 3

Solution 1 - Change directory structure and new script

  • First, create a new directory named new_root
  • Move the root directory to new_root
  • Create a new empty __init__.py inside the root directory. This will signal to the python intrepter that this directory is a package.
  • Create main.py in new_root directory

The project directory - solution 1
 new_root
 ├── program.py
 └── root
     ├── __init__.py
     ├── data.py
     └── package
         ├── __init__.py
         └── program.py
Updating new_root/program.py
 print('__file__={0:<35} | __name__={1:<25} | __package__={2:<25}'.format(__file__,__name__,str(__package__)))

 import root.package.program

When we invoke the new script, we get the following output:

Invoking program.py
 Y:/new_root>python program.py
 __file__=program.py                          | __name__=__main__                  | __package__=None
 __file__=Y:/new_root/root/package/program.py | __name__=root.package.program      | __package__=root.package
 __file__=Y:/new_root/root/data.py            | __name__=root.data                 | __package__=root
 data.size => 10

It works. Let's see why?
As we can see in the output, Importing root.package.program in main.py will set the package information - In other words, __name__ is no longer __main__ and package is no longer None. Now, when the python interpreter knows this information, it can successfully resolve the relative import in root/package/program.py successfully.

In this solution, we needed to create a new script. In the following solution, we use -m option without creating a new script.