我正在开发一个具有专有依赖关系且没有公共下载位置的包。如果pip
发现未安装此特定依赖项,我想要中止安装,或者打印警告并继续卸载依赖项。我想在我的最后配置它,可能在setup.py
,而不是用户在安装我的包时必须指定的内容。
我特别希望pip甚至尝试从任何地方下载或安装依赖项;特别是,如果pip尝试从PyPI下载依赖项,有人可以使用依赖项的名称注册一些不好的内容,pip会安装它。
有一些方法可以为应该从PyPI以外的其他地方下载的依赖项指定alternate download links,但我还没有找到一种方法可以说根本不应该下载依赖项。
我发现最好的解决方法是根本不依赖于install_requires
列表,但是没有迹象表明依赖存在,如果安装没有依赖的包,则没有警告。< / p>
有没有办法说不应该下载特定的依赖项?
答案 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()