I'm developing a python project that will have separately distributable parts.
I have been able to accomplish part of my goal by making a namespace package. I have "sub1" and "sub2", both in namespace "lvl1". I can pip install these in development mode using "pip install -e" or python setup.py develop
. I can import them with import lvl1.sub1
and import lvl1.sub2
.
However, the project is massive and calls for nested namespaces. I want to import lvl1.lvl2.sub1
and import lvl1.lvl2.sub2
. So both subpackages are in the same namespace ("lvl2"), which is itself in a namespace ("lvl1").
Desired conceptual structure:
lvl1/
lvl2/
sub1/
code.py
more_code.py
...
sub2/
code.py
...
Is there a way to do this and how?
Setuptools provides powerful tools to handle package discovery, including support for namespace packages. Normally, you would specify the packages to be included manually in the following manner: If your packages are not in the root of the repository or do not correspond exactly to the directory structure, you also need to configure package_dir:
Historically, there were two methods to create namespace packages. One is the pkg_resources style supported by setuptools and the other one being pkgutils style offered by pkgutils module in Python. Both are now considered deprecated despite the fact they still linger in many existing packages.
This is recommended if packages in your namespace only ever need to support Python 3 and installation via pip. Use pkgutil-style namespace packages. This is recommended for new packages that need to support Python 2 and 3 and installation via both pip and python setup.py install.
A complete working example of two native namespace packages can be found in the native namespace package example project.
Yes there is more than one way. Please read section "Nested namespace packages" in PEP 420.
In python >= 3.3, the easiest way to make nested namespace is to delete (do not include) file __init__.py
in the specific folders ("lvl1" and "lvl2") in every distributable parts. In each of the setup.py
, explicitly list all the packages in the deepest namespace.
"lvl1_part1/setup.py"
setup(
name='lvl1_part1',
...
zip_safe=False,
packages=['lvl1.lvl2.sub1']
)
"lvl1_part2/setup.py"
setup(
name='lvl1_part2',
...
zip_safe=False,
packages=['lvl1.lvl2.sub2']
)
The file structure for testing:
lvl1_part1/
setup.py
lvl1/
lvl2/
sub1/
__init__.py
lvl1_part2/
setup.py
lvl1/
lvl2/
sub2/
__init__.py
To make the above packages compatible to older python versions, please add the pkgutil
magic file to each of the "lvl1" and "lvl2" folders.
Credits: The example above is modified from https://github.com/pypa/sample-namespace-packages/tree/master/pkgutil
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With