Reputation: 1073
I can't seem to figure out how to fix the error below when trying to import a file from one directory up and it's making me crazy. Python 3.6.7.
Here's how The Internet
says it should be done, one directory up:
from .. import app
Here's the error:
Traceback (most recent call last):
File "module1.py", line 16, in <module>
from .. import app
ValueError: attempted relative import beyond top-level package
Here's the dir structure (It should be noted that I'm calling the script module1.py
from inside package1
):
--- project/
--- __init__.py
--- app.py
--- package1/
--- __init__.py
--- module1.py
Here's what I've tried to fix it:
Method 1 (same error)
import sys
HERE = Path(__file__).parent
sys.path.append(str(HERE / '../'))
from .. import app
Method 2 (found here, same error)
import os
import sys
sys.path.append(os.path.join(os.path.dirname(__file__)))
from .. import app
Method 3 ( also found here, same error)
import sys
sys.path.append('.')
from .. import app
Upvotes: 1
Views: 223
Reputation: 27311
A standard package structure for Python looks like this:
c:\srv\tmp> tree project
project
|-- project
| |-- __init__.py
| |-- app.py
| `-- package1
| |-- __init__.py
| `-- module1.py
`-- setup.py
where the project-root c:\srv\tmp\project
contains a setup.py
file and a subdirectory that is also named project
containing the source code.
The contents of module1.py
:
from .. import app
def module1_fn():
print("In module1, have imported app as:", app)
and the contents of setup.py
:
from setuptools import setup
setup(
name='project',
packages=['project'], # where to find sources
entry_points={
'console_scripts': """
module1-fn = project.package1.module1:module1_fn
"""
}
)
now the "magic" part, from the directory containing setup.py
run (note the .
at the end):
c:\srv\tmp\project> pip install -e .
Obtaining file:///C:/srv/tmp/project
Installing collected packages: project
Running setup.py develop for project
Successfully installed project
And now, from any directory, you can run:
c:\srv\tmp\project> module1-fn
In module1, have imported app as: <module 'project.app' from 'c:\srv\tmp\project\project\app.pyc'>
ie. module1-fn
can be called directly from the shell(!), and from .. import app
works directly(!!)
Upvotes: 2
Reputation: 12684
I got this working on my laptop so I hope it works on your side as well.
module1.py
import sys
from os import path
sys.path.append(path.join(path.dirname(__file__), '..'))
from app import print_app
print_app()
app.py:
def print_app():
print('success')
return None
Result:
$python module1.py
'success'
Upvotes: 1