So, this is the project structure:
<root directory>
- app
- - name
- - - module1
- - - module2
- - - module3
- - - - tests.py
- test_db.py
test_db.py contains an object called client
which I need in all the tests.py files in different modules.
I could simply move test_db.file inside the app directory but test_db.py needs to import app
from main.py which is again in the root directory and will cause the same issue again.
In every tests.py I need something like:
from ....test_db import client
but it just gets:
from ....test_db import client
E ImportError: attempted relative import beyond top-level package
So, I just can't figure out importing an object/package from the root directory.
P.S: I know one simple solution would be to change the directory structure a little, but It's a large project and changing the structure would be a LOT of work. So, ideally I need some way to add the root directory to the path inside every tests.py file. Something like this:
app/name/module3/tests.py:
import sys
#sys.path.something.. I am not really familiar with how to use this
from ....test_db import client #this should import client from test_db in root instead of throwing error
def test_create_todo():
pass
If you want to do a relative import without hacking around with sys.path
or custom loaders/finders, you need:
__init__.py
__main__
module (i.e. python -m root.stuff.main
)In short, this means you could add a directory project
to contain the test_db.py
and app
, add an __init__.py
, and call your program with python -m project.app.stuff.main
.
If this doesn't work for you (you mention you don't want to change the project structure) you do have other options.
You could install each as its own package (app
, and tests
). Create a setup.py
/setup.cfg
/pyproject.toml
, put test_db.py
in a package tests
, and pip install them as editable packages pip install -e .
. This will allow you to import either without relative imports (just import app
, and import tests.test_db
, regardless of file). This is personally the route I would go, and recommend doing.
Otherwise, if you're just looking for a quick fix, there exists one more easy + hacky solution. You could add the path for test_db.py
to sys.path
(every path in this list is explored for the target module when importing), so you could import test_db
from anywhere. Again, this is very hacky, and I don't recommend it beyond quick sanity checks or extremely urgent patches.