I am currently trying to group a number of related packages together in a parent package (meta_package). While doing so I also want one of the packages to be installable as a standalone package. To do this I created the following folder structure:
├── meta_package
│ ├── subpackage1
│ │ ├── module.py
│ │ ├── __init__.py
│ ├── subpackage2
│ │ ├── module.py
│ │ └── __init__.py
│ ├── subpackage3
│ │ ├── module.py
│ │ └── __init__.py
│ └── installable_subpackage
│ ├── README.md
│ ├── __init__.py
│ ├── requirements.txt
│ ├── setup.py
│ ├── installable_subpackage
│ │ ├── __init__.py
│ │ └── submodule
│ │ ├── __init__.py
│ │ └── module.py
Although the structure above achieves the desired result, both when defining the sub-packages as namespace packages or normal packages, it introduces an extra installable_subpackage
directory. As a result to import a Class from the installable_subpackage
I have to use the following import statement:
from meta_package.installable_subpackage.installable_subpackage.submodule.module import Class
I, however, would like to be able to import the Class using the following (shorter) import statement:
from meta_package.installable_subpackage.submodule.module import Class
What I already tried
Use name_space packages
I tried using namespace packages for the sub-packages instead of using normal packages. This, however, did not solve the extra folder problem and also introduced a number of python import traps.
Import the redundant folder (module) inside the installable_subpackage.init.py file
I also tried importing the installable_subpackage
submodule inside the installable_subpackage.__init__.py
file:
import meta_package.installable_subpackage.installable_subpackage
This however does not seem to work as the meta_package.installable_subpackage.submodule
import path does not point to the meta_package.installable_subpackage.installable_subpackage.submodule
module. I think this is because this method only works with Classes and not modules.
Use the setuptools packages and package_dir arguments
Lastly, according to this issue, I tried to use the setuptools
packages
and package_dir
arguments in the meta_package
setup.py get rid of the extra folder. To do this I used the following setup.py:
from setuptools import setup, find_namespace_packages
setup(
name="meta_package",
...
packages=find_namespace_packages(include=["meta_package.*"]),
package_dir={"meta_package.installable_subpackage": "meta_package/installable_subpackage/installable_subpackage"},
)
This, however, does also not seem to get rid of the extra folder.
Question
Is the packaging structure I am trying to achieve possible? Further, if so, is using it encouraged or advised against?
System information
- Python version: Python 3.8.5
- Virtual environment: Conda