I'm writing a python package with installable sub-packages as is shown below.
my_project
├── subpackage1
│ ├── foo.py
│ └── setup.py
├── subpackage2
│ ├── bar.py
│ └── setup.py
└── setup.py [main]
My setup.py is like the following:
from setuptools import setup, find_packages
from setuptools.command.install import install
# new install class
class InstallCommand(install):
# pass argument subpackage from pip install to setup.py
user_options = install.user_options + [
('subpackage=', None, None),
]
def initialize_options(self):
install.initialize_options(self)
self.subpackage = None
def finalize_options(self):
install.finalize_options(self)
def run(self):
if self.subpackage is None:
# install all sub-packages
subpackages = ['my_project.'+x for x in find_packages('./my_project', exclude=['*.tests', '*.tests.*', 'tests.*', 'tests'])]
self.distribution.packages += ['my_project'] + subpackages
else:
subpackages = self.subpackage.split(', ')
print("Install sub-packages:", self.subpackage)
# install only specific sub-packages
subpackages = ['my_project.'+x for x in subpackages]
self.distribution.packages += ['my_project'] + subpackages
install.run(self)
metadata = dict(
name='my_project',
packages=[],
install_requires=[],
setup_requires=[],
cmdclass={
'install': InstallCommand
}
)
setup(**metadata)
It allows me to install any sub-packges with a command like
$ pip install /path/to/main setup.py/ --install-option="--subpackage=subpackage1, subpackage2"
However, this setup.py doesn't install the dependencies for sub-packages I selected (sub-package dependencies are contained in install_requires of each sub-package setup.py).
Is there any way to have a dynamic install_requires argument for setup() based on the command line input "subpackage"?
I have tried to modify the function run(self) in the class InstallCommand(install) by adding
self.distribution.install_requires += dependency_ls_function of subpackage
but it messed up the command line input and makes the installation failed.
I also tried a very simple example with a package 'pipreqs', which is not installed in the environment.
self.distribution.install_requires += ['pipreqs']
The installation went well, but with a warning
my_project requires pipreqs, which is not installed.
I guess before the command 'install', the install_requires is already handled.