I created a python package which I use for brain preprocessing - named bpt
. I would also like to use the same package as a sub-module in another project named brain_seg
.
As a results, I am having problems with import statements which either results in errors when running the package stand-alone or nested.
The structure of the bpt
package is as follows:
bpt
|--__init__.py
|--module1.py
|--module2.py
|--run.py
Import statements in the file run.py
look something like:
import os
import module1
import module2
.
.
.
The structure of the brain_seg
package is as follows:
brain_seg
|--bpt
| |--__init__.py
| |--module1.py
| |--module2.py
| |--run.py
|
|--package2
| |--__init__.py
| |--module1a.py
|
|--__init__.py
When running the run.py
script which is part of the stand alone bpt
package, everything runs as expected.
If I try to run the same script as part of the brain_seg
package, the following error is dispatched:
ModuleNotFoundError: No module named 'module1'
I tried to use relative imports so the nested project will work as expected, resulting in the following run.py
file:
import os
from . import module1
from . import module2
.
.
.
Following the change, execution of the brain_seg
project worked as expected but when I tried to call the run.py
script from the stand alone bpt
package, it resulted in the following error being dispatched:
ImportError: attempted relative import with no known parent package
How should I handle the imports such that both options will be supported?
Imports in bpt.run
must be absolute or relative:
from bpt.module1 import ... # absolute
from .module1 import ... # relative
To run bpt.run
from your repository root with your pythonpath getting correctly set, use -m
:
python bpt/run.py # bad
python -m bpt.run # good
If brain_seg
is not truly meant to be a package itself, but just a project consisting of multiple packages and modules, get rid of brain_seg/__init__.py
.
If you do mean to use it as a package, then move it below the repo root, i.e.
- README.md (etc.)
- .gitignore (etc.)
- brain_seg
- __init__.py
- bps
- __init__.py
- main.py
and use e.g. python -m brain_seg.bps.run
from the repository root.
If you also intend to use bps
as a standalone thing, I wouldn't recommend keeping it in the brain_seg
hierarchy at all, but to make it pip install
able (see https://packaging.python.org/tutorials/packaging-projects/) and then pip install -e ../somewhere/bps
to have pip set up an editable link between your projects.