I can't for the life of me get python's relative imports to work. I have created a simple example of where it does not function:
The directory structure is:
/__init__.py
/start.py
/parent.py
/sub/__init__.py
/sub/relative.py
/start.py
contains just: import sub.relative
/sub/relative.py
contains just from .. import parent
All other files are blank.
When executing the following on the command line:
$ cd /
$ python start.py
I get:
Traceback (most recent call last):
File "start.py", line 1, in <module>
import sub.relative
File "/home/cvondrick/sandbox/sub/relative.py", line 1, in <module>
from .. import parent
ValueError: Attempted relative import beyond toplevel package
I am using Python 2.6. Why is this the case? How do I make this sandbox example work?
This question is related to
python
If you are going to call relative.py
directly and i.e. if you really want to import from a top level module you have to explicitly add it to the sys.path
list.
Here is how it should work:
# Add this line to the beginning of relative.py file
import sys
sys.path.append('..')
# Now you can do imports from one directory top cause it is in the sys.path
import parent
# And even like this:
from parent import Parent
If you think the above can cause some kind of inconsistency you can use this instead:
sys.path.append(sys.path[0] + "/..")
sys.path[0]
refers to the path that the entry point was ran from.
Checking it out in python3:
python -V
Python 3.6.5
Example1:
.
+-- parent.py
+-- start.py
+-- sub
+-- relative.py
- start.py
import sub.relative
- parent.py
print('Hello from parent.py')
- sub/relative.py
from .. import parent
If we run it like this(just to make sure PYTHONPATH is empty):
PYTHONPATH='' python3 start.py
Output:
Traceback (most recent call last):
File "start.py", line 1, in <module>
import sub.relative
File "/python-import-examples/so-example-v1/sub/relative.py", line 1, in <module>
from .. import parent
ValueError: attempted relative import beyond top-level package
If we change import in sub/relative.py
- sub/relative.py
import parent
If we run it like this:
PYTHONPATH='' python3 start.py
Output:
Hello from parent.py
Example2:
.
+-- parent.py
+-- sub
+-- relative.py
+-- start.py
- parent.py
print('Hello from parent.py')
- sub/relative.py
print('Hello from relative.py')
- sub/start.py
import relative
from .. import parent
Run it like:
PYTHONPATH='' python3 sub/start.py
Output:
Hello from relative.py
Traceback (most recent call last):
File "sub/start.py", line 2, in <module>
from .. import parent
ValueError: attempted relative import beyond top-level package
If we change import in sub/start.py
:
- sub/start.py
import relative
import parent
Run it like:
PYTHONPATH='' python3 sub/start.py
Output:
Hello from relative.py
Traceback (most recent call last):
File "sub/start.py", line 3, in <module>
import parent
ModuleNotFoundError: No module named 'parent'
Run it like:
PYTHONPATH='.' python3 sub/start.py
Output:
Hello from relative.py
Hello from parent.py
Also it's better to use import from root folder, i.e.:
- sub/start.py
import sub.relative
import parent
Run it like:
PYTHONPATH='.' python3 sub/start.py
Output:
Hello from relative.py
Hello from parent.py
Source: Stackoverflow.com