Python 不可下载的依赖项

Python 不可下载的依赖项,python,pip,setuptools,Python,Pip,Setuptools,我正在开发一个软件包,该软件包具有专有依赖性,没有公共下载位置。如果pip发现未安装此特定依赖项,我想中止安装,或者打印警告并继续卸载依赖项。我想在我这方面进行配置,可能是在setup.py中,而不是用户在安装我的软件包时必须指定的内容 我特别希望pip不要尝试从任何地方下载或安装依赖项;特别是,如果pip试图从PyPI下载依赖项,可能会有人用依赖项的名称注册一些不好的东西,pip会安装它 有一些方法可以指定应该从PyPI以外的其他地方下载的依赖项,但我还没有找到一种方法可以说不应该下载依赖项

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

我特别希望pip不要尝试从任何地方下载或安装依赖项;特别是,如果pip试图从PyPI下载依赖项,可能会有人用依赖项的名称注册一些不好的东西,pip会安装它

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

我发现的最好的解决办法是根本不将依赖项放在
install\u requires
列表上,但是如果您在没有依赖项的情况下安装软件包,则没有迹象表明存在依赖项,也没有警告

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

如果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分发,因为wheels在安装时不会调用
setup.py

$ python setup.py sdist
在缺少
numpy
时尝试安装内置tar将导致:

$pip install dist/spam-0.1.tar.gz
正在处理。/dist/spam-0.1.tar.gz
从命令python setup.py egg_info完成输出:
运行蛋_信息
创建pip鸡蛋信息/spam.egg-info
正在编写pip egg info/spam.egg-info/PKG-info
正在将依赖项链接写入pip egg info/spam.egg-info/dependency\u links.txt
将顶级名称写入pip egg info/spam.egg-info/top_level.txt
正在编写清单文件“pip egg info/spam.egg info/SOURCES.txt”
正在读取清单文件'pip egg info/spam.egg info/SOURCES.txt'
错误:未安装numpy。安装将中止。
----------------------------------------
命令“python setup.py egg_info”在/private/var/folders/_y/2qk6029j4c7bwv0ddk3p96r00000gn/T/pip-s8sqn20t-build中失败,错误代码为1/
请注意,我可以在安装脚本的顶部执行导入检查:

from setuptools import setup

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

setup(...)
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()
但在这种情况下,输出将不会格式化,完整的堆栈跟踪将溢出到标准输出,这太过技术化,可能会让用户感到困惑。相反,我将在安装时调用一个
distutils
命令作为子类,以便正确格式化错误输出

现在,关于第二部分:

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

这已经不可能了,因为版本7。只有当pip以详细模式运行时,用户才会看到安装脚本的输出,即
pip install-v mypkg
。如果你问我,这是一个值得怀疑的决定

不过,以下是在安装脚本中发出警告和错误的示例:

from setuptools import setup

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

setup(...)
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()

是否有
cmdclass
的文档?我找不到它。@user2357112它是Python stdlib的一部分。这应该是一个很好的起点。