setup.py 中的动态 install_requires

Che*_*nlu 5 python dependencies namespaces setuptools

我正在编写一个带有可安装子包的 python 包,如下所示。

\n\n
my_project\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 subpackage1\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 foo.py\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 setup.py\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 subpackage2\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 bar.py\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 setup.py\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 setup.py [main]\n
Run Code Online (Sandbox Code Playgroud)\n\n

我的 setup.py 如下所示:

\n\n
from setuptools import setup, find_packages\nfrom setuptools.command.install import install\n\n# new install class\nclass InstallCommand(install):\n    # pass argument subpackage from pip install to setup.py\n    user_options = install.user_options + [\n        (\'subpackage=\', None, None),  \n    ]\n\n    def initialize_options(self):\n        install.initialize_options(self)\n        self.subpackage = None\n\n    def finalize_options(self):\n        install.finalize_options(self)\n\n    def run(self):\n\n        if self.subpackage is None:\n            # install all sub-packages\n            subpackages = [\'my_project.\'+x for x in find_packages(\'./my_project\', exclude=[\'*.tests\', \'*.tests.*\', \'tests.*\', \'tests\'])]\n            self.distribution.packages += [\'my_project\'] + subpackages \n\n        else:  \n            subpackages = self.subpackage.split(\', \')\n            print("Install sub-packages:", self.subpackage)\n            # install only specific sub-packages\n            subpackages = [\'my_project.\'+x for x in subpackages]\n            self.distribution.packages += [\'my_project\'] + subpackages\n\n        install.run(self)\n\nmetadata = dict(\n    name=\'my_project\',\n    packages=[],\n    install_requires=[],\n    setup_requires=[],\n    cmdclass={\n        \'install\': InstallCommand\n    }\n    )\n\nsetup(**metadata)\n
Run Code Online (Sandbox Code Playgroud)\n\n

它允许我使用类似命令安装任何子包

\n\n
$ pip install /path/to/main setup.py/ --install-option="--subpackage=subpackage1, subpackage2"\n
Run Code Online (Sandbox Code Playgroud)\n\n

但是,此 setup.py 不会安装我选择的子包的依赖项(子包依赖项包含在每个子包 setup.py 的 install_requires 中)。

\n\n

有没有办法根据命令行输入“子包”为 setup() 提供动态 install_requires 参数?

\n\n

我尝试通过添加来修改 InstallCommand(install) 类中的函数 run(self)

\n\n
self.distribution.install_requires += dependency_ls_function of subpackage\n
Run Code Online (Sandbox Code Playgroud)\n\n

但它弄乱了命令行输入并导致安装失败。

\n\n

我还尝试了一个非常简单的示例,其中包含一个包“pipreqs”,该包未安装在环境中。

\n\n
self.distribution.install_requires += [\'pipreqs\']\n
Run Code Online (Sandbox Code Playgroud)\n\n

安装很顺利,但有一个警告

\n\n
my_project requires pipreqs, which is not installed.\n
Run Code Online (Sandbox Code Playgroud)\n\n

我猜想在命令“install”之前,install_requires 已经被处理了。

\n