python - setuptools和pip的依赖解析的区别

标签 python pip setuptools

我最近开始使用 SetupTools 打包我的第一个项目,并且大部分都取得了成功。

不幸的是,我遇到了一个令人困惑的情况——我的项目依赖于一个在 PyPI 上不可用的单文件模块。我已经能够使用 dependency_links 选项轻松地将 setup.py 配置为依赖于该模块,并且一切正常……只要我使用 setup.py 安装它。如果我尝试使用 pip 安装项目 egg,尝试安装模块时会失败,假设它必须是预制的 egg 存档。相比之下,setup.py 检测到它是一个简单的源文件并从中生成一个鸡蛋。

我的目标是让我的项目在 PyPI 上可用,因此仅使用 pip 即可安装它很重要;所以我的问题是......我做错了什么吗?

我的理解是 setuptools 本质上是达到目的的一种手段,即 pip 和 PyPI,所以我觉得这两个工具的行为如此不同对我来说很奇怪。

setup.py 的相关部分和每个工具的输出如下:

setup(
    name='particle-fish',
    version='0.1.0',
    description='Python Boilerplate contains all the boilerplate you need to create a Python package.',
    long_description=readme + '\n\n' + history,
    author='Lachlan Pease',
    author_email='predatory.kangaroo@gmail.com',
    url='https://github.com/predakanga/particle-fish',
    packages=[
        'particle.plugins'
    ],
    include_package_data=True,
    install_requires=['particle', 'irccrypt', 'pycrypto'],
    dependency_links=['http://www.bjrn.se/code/irccrypt/irccrypt.py#egg=irccrypt-1.0'],
    license="BSD",
    zip_safe=False,
    keywords='particle-fish',
    classifiers=[
        'Development Status :: 2 - Pre-Alpha',
        'Intended Audience :: Developers',
        'License :: OSI Approved :: BSD License',
        'Natural Language :: English',
        "Programming Language :: Python :: 2",
        'Programming Language :: Python :: 2.6',
        'Programming Language :: Python :: 2.7',
        'Programming Language :: Python :: 3',
        'Programming Language :: Python :: 3.3',
    ],
    test_suite='tests',
    tests_require=['pytest', 'mock', 'coverage', 'pytest-cov'],
    cmdclass = {'test': PyTest},
)

setup.py 安装的输出:
Installed /Users/lachlan/.virtualenvs/particle-fish/lib/python2.7/site-packages/particle_fish-0.1.0-py2.7.egg
Processing dependencies for particle-fish==0.1.0
Searching for irccrypt
Best match: irccrypt 1.0
Downloading http://www.bjrn.se/code/irccrypt/irccrypt.py#egg=irccrypt-1.0
Processing irccrypt.py
Writing /var/tmp/easy_install-svPfHF/setup.cfg
Running setup.py -q bdist_egg --dist-dir /var/tmp/easy_install-svPfHF/egg-dist-tmp-Xq3OCt
zip_safe flag not set; analyzing archive contents...
Adding irccrypt 1.0 to easy-install.pth file

pip 安装的输出:
Downloading/unpacking irccrypt (from particle-fish==0.1.0)
  Downloading irccrypt.py
  Cannot unpack file /private/var/tmp/pip-mCc6La-unpack/irccrypt.py (downloaded from /Users/lachlan/.virtualenvs/particle-staging/build/irccrypt, content-type: text/plain); cannot detect archive format
Cleaning up...
Cannot determine archive format of /Users/lachlan/.virtualenvs/particle-staging/build/irccrypt

最佳答案

你的问题有两个部分:

  • 处理dependency_links的正确方法是什么?通过 setup 指定?
  • 为什么没有得到一致的处理?


  • 处理dependency_links的正确方法是什么?通过 setup 指定?

    The setuptools documentationdependency_links 说这个setup 的参数方法:

    dependency_links
    A list of strings naming URLs to be searched when satisfying dependencies. These links will be used if needed to install packages specified by setup_requires or tests_require. They will also be written into the egg’s metadata for use by tools like EasyInstall to use when installing an .egg file.



    现在,这很模糊。他们确实提到了EasyInstall ,因此我们可以深入研究那里的源代码以确定它如何处理 dependency_links . Setuptools 还记录了鸡蛋的内部结构,which includes the dependency-links.txt file对应于 dependency_links setup 的参数.它让我们更深入地了解链接实际上应该是什么:

    A list of dependency URLs, one per line, as specified using the dependency_links keyword to setup(). These may be direct download URLs, or the URLs of web pages containing direct download links, and will be used by EasyInstall to find dependencies, as though the user had manually provided them via the --find-links command line option. Please see the setuptools manual and EasyInstall manual for more information on specifying this option, and for information on how EasyInstall processes --find-links URLs.



    (粗体强调我的)

    这很有用,因为它指出了它们应该如何处理,以及它实际期望什么。这个描述比 dependency_links 稍微有用一些。一、如它指定“要搜索的 URLS”的实际含义 :直接下载链接或包含它们的索引。源代码确认--find-linksdependency_links are actually merged when building the egg ,所以我们现在可以查看 --find-links EasyInstall 的参数以了解它的期望。

    --find-links=URLS_OR_FILENAMES, -f URLS_OR_FILENAMES
    Scan the specified “download pages” or directories for direct links to eggs or other distributions.



    那里有更详细的信息,但总体思路是 --find-links寻找鸡蛋或文件包含未找到的包。所以这是你谜团答案的第一部分: dependency_links用于指向完整的包,而不是单独的未打包模块。

    这听起来像 pip 如何处理链接 你包括在内,当你通读所有内容时,这是有道理的。您可以通过查看 pip 的测试来确认这一 pip 。 pip 有两个使用 dependency_links 的测试( 12 ),两者都假设 dependency_links is pointing to an indexing page .这似乎符合 setuptools 的描述,其中 dependency_links是“命名要搜索的 URL 的字符串列表”。

    所以,既然我们知道 pip 正在根据规范处理这个问题,那就留下第二个问题:

    为什么这与 setuptools 一起工作?

    为了理解为什么这与 setuptools 一起工作,您需要了解 setuptools 如何确定依赖项并尝试下载/安装它们。 PackageIndex.download method在任何外部 url 上调用,并且需要在本地下载软件包才能安装。此函数的文档字符串包含我们问题的答案:

    If it is the URL of a .py file with an unambiguous #egg=name-version tag (i.e., one that escapes - as _ throughout), a trivial setup.py is automatically created alongside the downloaded file.



    这就解释了为什么 setuptools 忽略了它不是一个发行版的事实,但是 pip 失败了。

    TL;DR: dependency_links应该指向包含一个包或存档,而不是未打包的模块。 Setuptools 意识到您的痛苦并帮助您解决问题,但这大多没有记录。如果许可证允许,请考虑重新打包模块并将其包含在您的包中。

    关于python - setuptools和pip的依赖解析的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18543222/

    相关文章:

    python - 如何在pkg_resources中实现resource_filename?

    Python--查找嵌套字典中特定值的父键

    virtualenv - 如何使用 pip 从本地缓存安装?

    python - 数据科学体验上的 AssertionError : Multiple . dist-info 目录

    python - 如何修复 "pip"?

    Python 安装工具 : first build from sources then install

    python - 索引错误: index 0 is out of bounds for axis 0 with size 0

    python - 卷积神经网络-Keras-val_acc Keyerror 'acc'

    python - 找出总和为最小值的那个

    python - setuptools 在安装过程中发现错误的包