无法下载的依赖项

时间:2017-11-30 20:38:11

标签: python pip setuptools

我正在开发一个具有专有依赖关系且没有公共下载位置的包。如果pip发现未安装此特定依赖项,我想要中止安装,或者打印警告并继续卸载依赖项。我想在我的最后配置它,可能在setup.py,而不是用户在安装我的包时必须指定的内容。

我特别希望pip甚至尝试从任何地方下载或安装依赖项;特别是,如果pip尝试从PyPI下载依赖项,有人可以使用依赖项的名称注册一些不好的内容,pip会安装它。

有一些方法可以为应该从PyPI以外的其他地方下载的依赖项指定alternate download links,但我还没有找到一种方法可以说根本不应该下载依赖项。

我发现最好的解决方法是根本不依赖于install_requires列表,但是没有迹象表明依赖存在,如果安装没有依赖的包,则没有警告。< / p>

有没有办法说不应该下载特定的依赖项?

1 个答案:

答案 0 :(得分:3)

  

如果pip发现未安装此特定依赖项,我想中止安装...

如果我理解正确,您只需尝试从setup.py中的该软件包导入模块,然后在ImportError中止,即可检查是否安装了专有软件包。举个例子,假设你应该中止安装的依赖是numpy

from distutils.command.build import build as build_orig
from distutils.errors import DistutilsModuleError
from setuptools import setup


class build(build_orig):

    def finalize_options(self):
        try:
            import numpy
        except ImportError:
            raise DistutilsModuleError('numpy is not installed. Installation will be aborted.')
        super().finalize_options()


setup(
    name='spam',
    version='0.1',
    author='nobody',
    author_email='nobody@nowhere.com',
    packages=[],
    install_requires=[
        # all the other dependencies except numpy go here as usual
    ],
    cmdclass={'build': build,},
)

现在,您应该将您的包分发为源tar,因为在安装时轮子不会调用setup.py

$ python setup.py sdist

在缺少numpy时尝试安装构建的tar将导致:

$ pip install dist/spam-0.1.tar.gz 
Processing ./dist/spam-0.1.tar.gz
    Complete output from command python setup.py egg_info:
    running egg_info
    creating pip-egg-info/spam.egg-info
    writing pip-egg-info/spam.egg-info/PKG-INFO
    writing dependency_links to pip-egg-info/spam.egg-info/dependency_links.txt
    writing top-level names to pip-egg-info/spam.egg-info/top_level.txt
    writing manifest file 'pip-egg-info/spam.egg-info/SOURCES.txt'
    reading manifest file 'pip-egg-info/spam.egg-info/SOURCES.txt'

    error: numpy is not installed. Installation will be aborted.

    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /private/var/folders/_y/2qk6029j4c7bwv0ddk3p96r00000gn/T/pip-s8sqn20t-build/

请注意,我可以在安装脚本之上进行导入检查:

from setuptools import setup

try:
    import numpy
except ImportError:
    raise DistutilsModuleError(...)

setup(...)

但是在这种情况下,输出将不会被格式化,并且完整的堆栈跟踪将溢出到stdout,这太技术性并且可能使用户感到困惑。相反,我子类化了一个将在安装时调用的distutils命令,以便错误输出格式正确。

现在,第二部分:

  

...或打印警告并继续卸载依赖项。

从第7版pip will swallow any output from your setup script开始,这是不可能的。仅当pip以详细模式运行时,用户才会看到设置脚本的输出,即pip install -v mypkg。如果你问我,这是一个值得怀疑的决定。

尽管如此,这是一个在设置脚本中发出警告和错误的示例:

from distutils.log import ERROR

class build(build_orig):

    def finalize_options(self):
        try:
            import numpy
        except ImportError:
            # issue an error and proceed
            self.announce('Houston, we have an error!', level=ERROR)
            # for warnings, there is a shortcut method
            self.warn('I am warning you!')
        super().finalize_options()