我最近开始使用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 install的输出:
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 install的输出:
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
答案 0 :(得分:3)
您的问题分为两部分:
dependency_links
处理setup
的正确方法是什么? 通过dependency_links
处理setup
来处理dependency_links
的正确方法是什么?
The setuptools documentation对setup
menthod的dependency_links
参数说明了这一点:
setup_requires
在满足依赖关系时命名要搜索的URL的字符串列表。如果需要安装tests_require
或.egg
指定的软件包,将使用这些链接。它们也将被写入egg的元数据,供EasyInstall等工具在安装EasyInstall
文件时使用。
现在,这很模糊。他们确实提到了dependency_links
,因此我们可以深入了解源代码,以确定它如何处理dependency_links
。 Setuptools还记录了鸡蛋的内部结构,which includes the dependency-links.txt
file对应setup
的{{1}}参数。它让我们更加深入地了解链接实际应该是什么:
依赖关系URL列表,每行一个,使用
dependency_links
关键字setup()
。 这些可能是直接的 下载URL或包含直接下载的网页的URL 链接,EasyInstall将使用它来查找依赖项,就好像 用户通过--find-links
命令手动提供了这些用户 行选项。请参阅setuptools手册和EasyInstall手册 有关指定此选项的详细信息,以及有关的信息 EasyInstall如何处理--find-links
个网址。
(大胆强调我的)
这很有用,因为它指出了应该如何处理它们以及它实际期望的内容。此描述比dependency_links
稍微有用,因为它指定“要搜索的URL”实际上意味着:直接下载链接或包含它们的索引。源代码确认--find-links
和dependency_links
are actually merged when building the egg,因此我们现在可以查看EasyInstall的--find-links
参数,以了解它的期望。
--find-links=URLS_OR_FILENAMES, -f URLS_OR_FILENAMES
扫描指定的“下载页面”或目录,以获得与蛋或其他发行版的直接链接。
那里有更详细的信息,但一般的想法是--find-links
正在寻找包含未找到的包的鸡蛋或档案。因此,您的神秘答案的第一部分是: dependency_links
用于指向完整的包,而不是单独的未打包的模块。
这听起来像pip处理你所包含的链接,这在你阅读所有内容时都有意义。您可以通过查看pip具有的测试来确认这一点。 pip有两个使用dependency_links
(1,2)的测试,两者都假定为dependency_links
is pointing to an indexing page。这似乎与setuptools中的描述一致,其中dependency_links
是“命名要搜索的URL的字符串列表”。
所以,既然我们知道pip正在根据规范处理这个问题,那就留下了第二个问题:
为什么这适用于setuptools?
为了理解为何使用setuptools,您需要了解setuptools如何确定依赖关系并尝试下载/安装它们。在任何外部网址上调用PackageIndex.download
method,并要求在本地下载软件包进行安装。该函数的docstring包含我们问题的答案:
如果是具有明确
#egg=name-version
标记的.py文件的网址(即,-
全部为_
,则为setup.py
)与下载的文件一起自动创建。
这就解释了为什么setuptools忽略了它不是分布的事实,但是pip失败了。
TL; DR: dependency_links
应指向包含一个的包或存档,而不是未打包的模块。 Setuptools实现了你的痛苦并帮助你,但这几乎没有记录。如果许可证允许,请考虑重新打包模块并将其包含在您的软件包中。