通过 `setup.py develop` 安装失败 - pip 可用

15

我的Python包 footools 需要通过 setup.py 中的 install_requires 安装 html5lib

setup.py develop 安装失败

尝试使用 setup.py develop 进行安装时失败:

cd src/footools/
python setup.py develop

Processing dependencies for footools==2016.205
Searching for html5lib==0.9999999
Reading https://source.example.com/pypi/simple/html5lib/
Download error on https://source.example.com/pypi/simple/html5lib/: 
   [Errno 185090050] _ssl.c:354: error:0B084002:x509 
   certificate routines:X509_load_cert_crl_file:system lib -- 
   Some packages may not be found!
Couldn't find index page for 'html5lib' (maybe misspelled?)

pip 工作正常

但是直接下载也可以使用:

bar@workdevel123:~/src/footools> pip install html5lib==0.9999999
/home/bar/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/util/ssl_.py:79: 
InsecurePlatformWarning: A true SSLContext object is not available. 
This prevents urllib3 from configuring SSL appropriately
and may cause certain SSL connections to fail. 
For more information, see 
https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
  InsecurePlatformWarning
Collecting html5lib==0.9999999
/home/bar/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/util/ssl_.py:79: 
    InsecurePlatformWarning: A true SSLContext object is not available. 
    This prevents urllib3 from configuring SSL appropriately and
    may cause certain SSL connections to fail. 
    For more information,
    see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
  InsecurePlatformWarning
  Downloading https://source.example.com/pypi/packages/html5lib-0.9999999.tar.gz
Requirement already satisfied (use --upgrade to upgrade):
six in /usr/lib/python2.7/site-packages (from html5lib==0.9999999)
Installing collected packages: html5lib
  Running setup.py install for html5lib
Successfully installed html5lib-0.9999999

问题

这两种方法有什么区别?

它们为什么不同?

在Python中安装依赖的正确方式是什么?

setup.py

setup.py并没有特殊之处:

import setuptools

setuptools.setup(
    name='foo',
    version='2016.210',
    long_description=open('README.txt').read(),
    packages=setuptools.find_packages(),
    install_requires=[
        # about twenty packages before this line
        'html5lib==0.9999999'
],
    include_package_data=True,
    entry_points={
        'console_scripts': [
            'foo=foo.utils.bar:main',
        ],
    },
)

请提供您的 setup.py 文件,好吗? - rll
@rll 我添加了一个简化版本的 setup.py。它没什么特别之处。 - guettli
3个回答

11

python setup.py develop 或者说 setuptools 通常使用 easy_install 来满足其依赖关系,而后者又使用 urllib2,然而 pip 使用的是 requests。有关 easy_install vs pip 的详细信息,请参见此处。

pip 更现代化,除其他功能外,还具备卸载包和符合 PEP 438 -- Transitioning to release-file hosting on PyPI 的能力。你可以通过 pip install -e src/footools/ 来实现与 python setup.py develop 相同的功能,注意如果项目路径在当前目录中,使用 ./footools

requests 包将 CA 证书捆绑在包本身中,python -c 'import pip;print(pip.download.requests.certs.where())'

setuptools 使用系统安装的 CA 证书 python -c 'from setuptools import ssl_support;print(ssl_support.cert_paths)'

你需要使用像 update-ca-certificates 这样的工具更新系统安装的 CA 证书,以便自动更新 CA 证书或从https://curl.haxx.se/docs/caextract.html 下载并安装到 setuptools 显示的路径之一,或将 setuptools.ssl_support.cert_paths 设置为空序列,如[],然后执行 pip install certifi
调用 setuptools.ssl_support.find_ca_bundle() 将显示 CA 证书的位置。


我仍然不理解整个Python打包细节。这句话正确吗?“如果我调用python setup.py develop,那么将使用easy_install。Pip不使用easy_install”。如果是这样,我会问自己:为什么有两种方式? - guettli
@guettli 你说得对。关于“为什么有两种方式?”请参见 easy_install vs pip 链接。我已经更新了答案。 - Nizam Mohamed

2

setuptools 是 Python distutils 的增强集合(适用于 Python 2.6 及以上版本),允许开发人员更轻松地构建和分发 Python 包,尤其是那些依赖其他包的包。

因此,除了其他内容之外,您可以创建可以上传到 Pypi 的软件包,并使用 pip 安装它们(从而分发您的模块)。

话虽如此,在安装部分实际上不应该有太大差异。您正在运行 develop 模式,因此可能需要稍微调整一下目录或修复授权错误。

开发模式中,项目被部署到一个临时区域(类似于虚拟环境的过程)

部署是以这样一种方式进行的:对项目源代码的更改立即在临时区域中可用,而无需在每个更改后运行构建或安装步骤。

这也意味着所有内容都将对该 Python 解释器可用。稍后可以取消暂存。

我注意到 html5lib 从不同的地方获取:/pypi/simple//pypi/packages/

dependency_links 是一个字符串列表,命名要在满足依赖关系时搜索的 URL。如果需要安装由 setup_requires 或 tests_require 指定的软件包,则将使用这些链接。

回到问题上,我认为最可能是 ssl 问题,因为在 pip 中它处理得很好(即,有良好的警告和某种解决方法),但是 setuptools 不会出现相同的情况。如果请求中存在未处理的错误,则可能会出现 Couldn't find index page for 'html5lib'


setup.py developpip install ...不是做同样的事情吗?它们有什么区别? - guettli
谢谢您的解释。看起来在Python中获取/安装软件有两个代码库:setuptools和pip。我只是在想:为什么会这样? - guettli
没有看到配置,我无法添加太多内容...你是否使用了dependency_links - rll

1

这两种方法有什么区别?

对于用户来说,除了不同的用户界面,没有什么重要的区别。它们是 Python 包管理历史中的两个站点。在这之前还有其他站点。

它们为什么不同?

早些时候,Python 没有自带的包管理系统。第三方解决方案填补了这一空白。它们是由不同的人在不同的时间设计的。如果你看看其他编程语言,有时会看到类似的故事;有时会看到更幸福的故事;有时则更悲惨。

在 Python 中安装依赖项的正确方法是什么?

这两种方法都是技术上正确的。Pip 是更现代的方法,在我的经验中它更受欢迎并且更方便使用。从 Python 3.4 开始,Pip 已经包含在 CPython 发行版中,并且被官方“推荐”。所以你可以看出风向。


Nizam Mohamed涵盖了示例中具体故障背后的细节,但正如他所指出的那样,这并不完全是软件包管理器的错 - 还涉及一些系统组件。 - ben author

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接