3

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
Shishir Pandey
  • 832
  • 1
  • 12
  • 23

1 Answers1

5

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.

Brian Burns
  • 20,575
  • 8
  • 83
  • 77
Jean-Paul Calderone
  • 47,755
  • 6
  • 94
  • 122
  • I get the error (beyond top-level): ```ValueError: attempted relative import beyond top-level package```, and not the "non-package" – Shishir Pandey Sep 04 '17 at 15:35
  • 1
    I'm not sure the particular text of the exception matters much. It's true you're encountering a slightly different error path than I demonstrated. However, the underlying cause of both errors is the same. Use of a source file which is meant to be a sub-package as though it were a top-level script. If you avoid that then you'll be safe from this class of errors. – Jean-Paul Calderone Sep 04 '17 at 15:49