Reputation: 19627
I am working on a python library (not mine) which looks like this:
.
├── README.md
├── setup.py
└── library
├── __init__.py
├── core.py
├── a.py
└── b.py
The file __init__.py
make use of core.py
which itself uses a.py
and b.py
. The important thing to note is that import library
has some side effets which are deliberately intended.
However, I would like to give the user the possibility to use functions of core.py
without there being any side effects. Unfortunately, as you know, import library.core
or from library import core
will execute __init__.py
(where side effects occur) anyway.
Do you know how could I reorganize my package and the setup.py
to solve this problem?
I thought to something like this:
.
├── README.md
├── setup.py
├── library_core
│ ├── __init__.py
│ ├── core.py
│ ├── a.py
│ └── b.py
└── library
└── __init__.py # Import library_core and apply side effects
I would update setup.py
with packages = ['library', 'library_core']
. That way, importing library
do not change anything, but user could then import library_core
without any side effects. Also, this would avoid duplicating code and everything would stay in the same repository.
Unfortunately, this does not work because I do not have the ability to import library_core
from library
since they are not in the same place in the file tree.
Upvotes: 1
Views: 1743
Reputation: 19627
Using two package seems to be the best way.
The use of two adjacent packages can work only if the whole library is installed (with python setup.py install
for example). This complicates development considerably, for unit tests for example: it was then impossible to do import library
since library_core
could not be found if not installed.
So, the best solution is to simply make a sub-package, and specify within the setup.py
where library_core
is located thanks to the package_dir
option.
The files tree would look like this:
.
├── README.md
├── setup.py
└── library
├── __init__.py
└── core
├── __init__.py
├── a.py
└── b.py
And in setup.py
:
setup(
name = 'library',
packages = ['library', 'library.core', 'library_core'],
package_dir = {'library_core': 'library/core'},
...
)
Upvotes: 0
Reputation: 37033
I'd recommend that you stop relying on side effects and require the user to explicitly trigger them by calling a documented function. Otherwise you are fighting a losing battle: the default is currently to trigger the side effects, and then you have to undo them if the user doesn't want them.
Upvotes: 1