关于Setuptools及其替代方案的问题
最近我在网上看到很多人对setuptools不太满意。最近我读了James Bennett的一篇文章,标题是《关于打包》,里面说没人应该使用setuptools。在Freenode的#python频道里,我知道有一些人非常讨厌它。我自己也算是其中之一,但我确实在用它。
我用setuptools做过不少项目,知道它的一些缺点,我希望能有更好的工具。我不太喜欢它的egg格式和部署方式。尽管setuptools有很多问题,我还是没找到更好的替代品。
我理解像pip这样的工具是用来替代easy_install的(而不是setuptools)。实际上,pip还用了一些setuptools的组件,对吧?
我大多数的包都使用了一个支持setuptools的setup.py文件,这个文件声明了所有的依赖。当准备好后,我会构建sdist、bdist和bdist_egg,并把它们上传到pypi。
如果我想换成使用pip,我需要做哪些改动才能摆脱easy_install的依赖?依赖是在哪里声明的?我猜我需要放弃egg格式,只提供源代码分发。如果是这样,我该如何生成egg-info目录?或者我根本不需要生成它们吗?
这会如何改变我使用virtualenv的方式?难道virtualenv不是用easy_install来管理环境的吗?
这会如何影响我使用setuptools提供的“develop”命令?我应该不使用这个吗?那有什么替代方案?
我基本上是在试图了解我的开发工作流程会是什么样的。
在有人建议之前,我并不想要依赖于操作系统的解决方案。我主要关注的是debian linux,但出于Ian Bicking在这里提到的原因,deb包不是一个选项。
3 个回答
我写这篇文章是在2014年4月。提到关于Python打包、分发或安装的任何内容时,大家要注意一下日期。过去三年里,似乎在这些方面的争论减少了,实施也有所改善,PEP(Python增强提案)标准化和统一的进展也在加快。
比如,Python打包管理机构是一个工作组,负责维护许多与Python打包相关的项目。
python.org
上的Python打包用户指南里有工具推荐和Python打包的未来这两个部分。
distribute
是setuptools
的一个分支,2013年6月重新合并回来了。指南中提到,“使用setuptools
来定义项目并创建源分发。”
根据PEP 453和Python 3.4,指南建议,“使用pip
从PyPI安装Python包。”而pip
是Python 3.4自带的,并且在虚拟环境中通过pyvenv
安装,这个也是自带的。你可能会对PEP 453的“理由”部分感兴趣。
指南中还提到了新工具和一些比较新的工具,包括wheel
和buildout
。
我很高兴读了以下两篇技术/半政治历史文章。
Martijn Faassen在2009年写的:Python打包的历史。
Armin Ronacher在2013年6月写的(标题不太严肃):Python打包:到处都是仇恨。
首先,pip是个新东西。它刚出来不久,功能还不全,而且在实际使用中测试得也不够多。
虽然它有很大的潜力,但在它能做到easy_install/setuptools能做的所有事情之前,可能不会被广泛接受,尤其是在公司里。
easy_install/setuptools功能强大而复杂,这让很多人感到不满。不过,这种复杂性是有原因的,因为它能满足很多不同的使用场景。我自己的情况是要支持超过300个桌面用户,还有一个类似规模的系统,应用程序经常更新。如果让每个用户都从源代码安装,那简直是天方夜谭——而且使用“egg”这种方式已经证明是一个可靠的项目分发方法。
我的建议是:学会使用setuptools——它真的很棒。大多数讨厌它的人其实是不理解它,或者根本没有需要那么全面的分发系统。
:-)
pip是一个用来安装Python包的工具,它使用了Setuptools,并且不需要对包进行任何修改。实际上,它是通过Setuptools来安装包的,使用的是:
python -c 'import setuptools; __file__="setup.py"; execfile(__file__)' \
install \
--single-version-externally-managed
因为它使用了这个选项(--single-version-externally-managed
),所以它不会把包安装成压缩文件,也不支持同时安装多个版本的软件,而且包的安装方式是扁平化的(就像使用python setup.py install
时只用distutils一样)。不过,包的元数据仍然会被安装。pip和easy_install一样,会下载并安装一个包的所有依赖项。
另外,你还可以使用一个需求文件来批量添加其他需要安装的包,并且可以更精确地指定版本要求(而不需要把这些具体要求放在你的setup.py
文件里)。但如果你不创建需求文件,那你就可以像使用easy_install那样直接使用pip。
对于你的install_requires
,我不建议做任何修改,除非你已经在这里尝试创建一些非常精确的要求,并且这些要求是经过验证的。我认为在setup.py
文件中对版本的要求有一个限度,因为你无法真正知道未来新库的兼容性如何,所以我不建议你去预测这些。需求文件是一个可以用来列出保守版本要求的替代方式。
你仍然可以使用python setup.py develop
,实际上如果你执行pip install -e svn+http://mysite/svn/Project/trunk#egg=Project
,它会把项目检出(到src/project
目录),然后在其上运行setup.py develop
。所以这个工作流程其实没有什么不同。
如果你以详细模式运行pip(比如pip install -vv
),你会看到很多运行的命令,而且你可能会认出大部分命令。