【问题标题】:Allowing a python package requirement to fail in setup允许 python 包要求在设置中失败
【发布时间】:2014-08-16 11:46:28
【问题描述】:

是否有一种标准方法可以让 python 包的要求在包设置脚本中失败?

我正在创建一个类似于Python Social Auth 的包,因为它有许多提供者。

是否有一种标准方法可以让某些提供程序的安装要求失败,但仍然可以正常安装软件包?

【问题讨论】:

标签: python pip setuptools setup.py


【解决方案1】:

用户在安装时指定的可选依赖项:

setup()可以使用extras_require参数:http://pythonhosted.org/setuptools/setuptools.html#declaring-extras-optional-features-with-their-own-dependencies

setup(
    name="MyProject",
    ...
    extras_require = {
        'ProviderX':  ["DependencyX1", "DependencyX2"],
        'ProviderY': ["DependencyY"],
    }
)

通过这种方法,用户可以要求安装特定的扩展pip install Myproject[ProviderX]

基于现有包的可选依赖项:

为了自动检测已安装的包,您可以动态构建需求列表。例如,您可以查看 matplotlib 是如何做到这一点的(它们有许多可选的绘图后端):https://github.com/matplotlib/matplotlib

基本上,setup.py 只是普通的 python 代码,因此您可以运行一个检查可选依赖项的函数,并相应地调整要求和要安装的包列表。

matplotlib 这样做的方式是为依赖项定义一个类,它为每个依赖项扩展(在 setupExt.py 中)。

class SetupPackage(object):
    optional = False

    def check(self):
        """
        Checks whether the dependencies are met. [...]
        """
        pass

    def get_packages(self):
        """
        Get a list of package names to add to the configuration.
        These are added to the `packages` list passed to
        `distutils.setup`.
        """
        return []

    def get_namespace_packages(self):
        """
        Get a list of namespace package names to add to the configuration.
        These are added to the `namespace_packages` list passed to
        `distutils.setup`.
        """
        return []


    def get_py_modules(self):
        """
        Get a list of top-level modules to add to the configuration.
        These are added to the `py_modules` list passed to
        `distutils.setup`.
        """
        return []

    ...

class Numpy(SetupPackage):
    ...

然后它遍历 setup.py 中的每个依赖项,检查是否应该安装它,并相应地扩展每个列表以传递给 setup()

mpl_packages = [
    'Building Matplotlib',
    setupext.Six(),
    setupext.Dateutil(),
    ...

good_packages = []
for package in mpl_packages:
    [...]
    # check and append
    if ...
        good_packages.append(package)

[...]
for package in good_packages:
    if isinstance(package, str):
        continue
    packages.extend(package.get_packages())
    namespace_packages.extend(package.get_namespace_packages())
    py_modules.extend(package.get_py_modules())
    ext = package.get_extension()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-01
    • 1970-01-01
    • 2020-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多