Python3: Relative import beyond toplevel

675 views Asked by At

Yes, there are similar questions, but they do not answer my issue. My directory structure is as follows, all __init__.py files are blank.

Package/
    __init__.py
    sub_package1/
           __init__.py
           file1.py
    sub_package2/
            __init__.py
            file2.py

In file2.py I have the following code:

from ..sub_package1 import file1

I get the error mentioned above,

ValueError: attempted relative import beyond top-level package

There are a number of scikit-learn packages which do similar imports and it works for them.

Command that raised the error:

  1. working directory: Package/
  2. Command: python /path/to/Package/sub_package2/file2.py
1

There are 1 answers

2
Jean-Paul Calderone On BEST ANSWER

Whether or not relative imports work depends on how you invoke the code, unfortunately.

$ mkdir Package Package/sub_package{1,2} 
$ touch Package/__init__.py Package/sub_package{1,2}/__init__.py
$ touch Package/sub_package1/file1.py
$ echo "from ..sub_package1 import file1" > Package/sub_package2/file2.py

$ python Package/sub_package2/file2.py 
Traceback (most recent call last):
  File "Package/sub_package2/file2.py", line 1, in <module>
    from ..sub_package1 import file1
ValueError: Attempted relative import in non-package

$ python -m Package.sub_package2.file2
$

When you python Package/sub_package2/file2.py the runtime doesn't recognize that Package/sub_package2 is part of the module path. It thinks the module you're working with is just file2. So it cannot interpret the .. relative import.

When you import the module using its full path, as python -m ... does (and as any normal import statement will do), the full import path is recognized and relative imports can be interpreted properly.