代码之家  ›  专栏  ›  技术社区  ›  Michael Scott Asato Cuthbert

默认情况下,在Python中安装“可选”依赖项(setuptools)

  •  5
  • Michael Scott Asato Cuthbert  · 技术社区  · 7 年前

    有没有一种方法可以指定Python包的可选依赖项 从…起 pip 但是,如果无法安装,则不应将哪个安装视为失败?

    我知道我可以具体说明 install_requires 因此,这些软件包将为90%使用操作系统的用户安装,这些操作系统可以轻松安装某些可选的依赖项,我也知道我可以指定 extra_require 指定用户可以声明他们希望完整安装以获得这些功能,但我还没有找到一种默认方法 皮普

    (我要更新的特定软件包 setuptools 和 setup.py 因为它被称为 music21 其中95%的工具可以在没有matplotlib、IPython、scipy、pygame、一些模糊的音频工具等的情况下运行。但是如果安装了这些软件包,该软件包将获得额外的功能和速度,我更愿意让人们默认拥有这些功能,但如果无法安装,则不报告错误)

    3 回复  |  直到 7 年前
        1
  •  6
  •   mingaleg    7 年前

    无论如何,这不是一个完美的解决方案,但您可以设置一个安装后脚本来尝试安装软件包,如下所示:

    from distutils.core import setup
    from distutils import debug
    
    
    from setuptools.command.install import install
    class PostInstallExtrasInstaller(install):
        extras_install_by_default = ['matplotlib', 'nothing']
    
        @classmethod
        def pip_main(cls, *args, **kwargs):
            def pip_main(*args, **kwargs):
                raise Exception('No pip module found')
            try:
                from pip import main as pip_main
            except ImportError:
                from pip._internal import main as pip_main
    
            ret = pip_main(*args, **kwargs)
            if ret:
                raise Exception(f'Exitcode {ret}')
            return ret
    
        def run(self):
            for extra in self.extras_install_by_default:
                try:
                    self.pip_main(['install', extra])
                except Exception as E:
                    print(f'Optional package {extra} not installed: {E}')
                else:
                    print(f"Optional package {extra} installed")
            return install.run(self)
    
    
    setup(
        name='python-package-ignore-extra-dep-failures',
        version='0.1dev',
        packages=['somewhat',],
        license='Creative Commons Attribution-Noncommercial-Share Alike license',
        install_requires=['requests',],
        extras_require={
            'extras': PostInstallExtrasInstaller.extras_install_by_default,
        },
        cmdclass={
            'install': PostInstallExtrasInstaller,
        },
    )
    
        2
  •  2
  •   Dustin Ingram    7 年前

    setup.py :

    import sys
    import subprocess
    from setuptools import setup
    from setuptools.command.install import install
    
    class MyInstall(install):
        def run(self):
            subprocess.call([sys.executable, "-m", "pip", "install", "whatever"])
            install.run(self)
    
    setup(
        ...
    
        cmdclass={
            'install': MyInstall,
        },
    )
    

    hoefling 如上所述,这将 只有 如果发布源发行版,则可以工作( .tar.gz 或 .zip ). 如果您将包发布为内置发行版,则它将不起作用( .whl

        3
  •  0
  •   Samie Bee    7 年前

    这可能就是你要找的。它似乎是安装工具的内置功能,允许您声明“可选依赖项”。

    https://setuptools.readthedocs.io/en/latest/setuptools.html#declaring-extras-optional-features-with-their-own-dependencies

    setup(
        name="Project-A",
        ...
        extras_require={
            'PDF':  ["ReportLab>=1.2", "RXP"],
            'reST': ["docutils>=0.3"],
        }
    )