python代码库-Python打包库

Python打包库

译者:徐宏富

Sun-2014-05-25 blog.ionelmc.ro

我认为应该重新审视打包最佳做法,现如今,有许多的好的工具没有被使用过,或被充分使用。重新评估最佳的做法,通常来说一直都是件好事情。

例如,现在你的python代码包要在多个python版本中测试,这些版本有着不同的依赖库和设置等。

在打包时,我喜欢遵循一些基本的原则:

.如果你可以使用py.test或者nose这样的工具帮助测试,就不要浪费时间去建一个专有的运行测 试器。因为这些庞大的插件生态系统能够改进你的测试。

.如有可能,尽早阻止问题发生。这主要是要设计严格而详细的测试,去阻止一些常见的错误。

.收集覆盖数据,记录下来,甄别原因。

.测试所有可能的配置。

结构

这是相当重要的,每一件事都围绕着它。我比较喜欢如下类型的布局:

1441821-20181106160754496-839667950.png

这种src目录是一种很好的途径,是因为:

.你得到了导入入口。这个当前目录隐含着系统路径(sys.path)。假如你用site-pakages来进行安装或导入,就不是这样了。用户就不会和你一样,有着相同的当前工作目录。

.这样的约束,使得测试和打包均受益:

你将不得不检测安装代码(例如:安装某种虚拟环境),这能确保代码开发工作--打包代码是正确的,否则你的测试会失败。早早的,在你公开发布这样的有问题的软件包前,就能发现问题。

.你将不得不安装这些软件包。如果你曾经在pypi发布过软件包,由于没测试过安装配置,当遇到这些软件包缺少模板或者使用了破损的依赖库时,就不会上传成功。只有成功的建立源分发(sdist)模式,才能确保安装成功。

.这能预防你从setup.py脚本里导入代码。从主包或者模型里导入这些不可用的依赖库时,是糟糕的令人气炸的体验。首先就得避免这种可能发生。

.更简单的打包代码和表现形式。这种表现形式简单易写。例如你打包一个有许多模块和文件的Django APP时。同样的,你在面对有多个包的大型库时也不必担心。这样写,被打包的代码和打包用的代码一目了然。

没有src而去写manifest.in 文档是很困难的。如果你的manifest.in文档是破损的,你的测试也会失败。有src目录就会容易很多:你只须把src移植放入manifest.in文档里。

把破损的软件发布到pypi上不好处理。

没有src,在你编辑安装命令时就会很混乱(是用”setup.py develop” 还是用 "pip install -e”?)。没有代码分离src目录,就会迫使setuptools工具把你的项目根目录安装在系统路径(sys.path)上。这样就会充满大量的没用的东西,造成setup.py文档,还有其他的测试或配置脚本不知不觉的不能导入。

这里有个更好的工具--tox,你不需要处理安装包,只需要进行测试。你不必担心,它可以自动自如的帮你安装好软件包。

更少的用户错误出现。甚至几乎没有。

各种工具也不会混淆代码和非代码。

有一种说法是:扁平比嵌套好。但对数据来说并非如此。文件系统毕竟也是数据,紧凑、标准化的数据结构是可取的。

您会注意到我没有在已安装的软件包中包含测试。这是因为:

模块发现工具将会和你的测试模块冲突。奇怪的事情通常出现在测试模块中。内置help帮助就是模块发现。例如:

1441821-20181106161027864-1032404050.png

测试通常要额外的对象运行,它们自身没什么用,你不能直接空空的运行它们。

测试与开发有关,而不是用途。

库的用户不可能代替库的开发者去测试库,例如:当你测试app时,你没有去测试Django---因为Django已经测试过了。

备选方案

你可以这样用src--更少的布局,很少的例子。

1441821-20181106161206888-514042528.png

这两种布局变得流行是因为,几年前,打包时有很多问题,只为测试而安装打包是不可行的。人们还在推荐它们,仅仅是旧的和过时的假设。

很多项目不当的使用它们,是因为除了Twisted trial外,很多的测试运行器,都有不正确的当前工作目录默认值。如果你没有检测已经安装好的代码,就会错误的去检测的别的代码。Trial通过暂时改变当前工作目录去做正确的事情,而很多项目没有使用trial。

Setup 脚本

很不幸,当前的打包工具有很多的陷阱。Setup.py脚本应该尽量简单。

1441821-20181106161254788-1076395058.png

1441821-20181106161308837-1640991930.png

1441821-20181106161326932-1280081752.png

1441821-20181106161347137-227210042.png

1441821-20181106161415841-736163408.png

上面的脚本的特点:

.没有exec 或者 import 权略

.所有东西来自src--包或者根级别模块

.明确的编码

运行测试

再一次,人们倾向于用python setup.py test 去运行软件包测试。我认为并不值得这么去做,setup.py test 是个失败的试验,它尝试着去复制CPAN的测试系统。Python没有个通用的测试结果协议,所以它也没有个通用的测试命令,去达成目的。就目前来说,我们需要有人去建立规格和服务,以便值得我们这样去做,并支持他们。认识到失败在哪里,并在必要的时候能重新回到图板,我认为这是很重要的。毫无疑问,没相应的服务和工具,是在用setup.py test命令,提供这种增值服务的。有些事情错的很明显。

我认为,pypi现在去做这件事情已经为时过晚,因为现在有一个牢靠的、自由的、非常有弹性的候选者---Travis。它已经和Github紧紧的整合在一起,能自动获得Pull-Rquest支持。

Tox是一款很好的当地测试工具,它能运行所有可能的配置(每一种配置就一个tox环境)。我喜欢把这些测试用这些环境条件组成一个矩阵:

.检测 检测包裹的元数据。比如,重组文本在你的详细描述中是否有效。

.清理 清理覆盖数据

.报告 用所有累积的数据生成报告

.文档 生成sphnix文档

无论有没有测量覆盖率,我一直都喜欢用环境去测试。如果你总是用覆盖率去测量,你就不大可能捕获到,各种竞争条件下敏感的表现变化。

测试矩阵

根据依赖关系,你最终会得到各种python版本、依赖库版本、不同的设置的巨大组合。通常的,人们在tox.ini或者仅仅在.travis.yml中对所有的东西硬编码。在没有完成本地测试,或者在travis中进行连续测试完成前,这些测试就结束了。我那样做过,不喜欢这样。我尝试过在tox.ini和.travis.yml中复制所有环境,还不是喜欢它。

由于没有现成可用的选择去生成配置,我用模块生成器脚本去生成tox.ini和.travis.yml。这种方法更好,很干净,你很容易跳过特定的环境测试(例如,跳过Django 1.4 在Python 3中的测试),只需要做少量的改动工作。

要点(全部代码)

1441821-20181106161640595-104246710.png

1441821-20181106161658692-1247376020.png

Ci/bootstrap.py

这是生成器脚本。无论什么时候,你想生成配置就运行它。

1441821-20181106161726097-1363076247.png

1441821-20181106161746331-2097224445.png

1441821-20181106161811614-541701551.png

1441821-20181106161827849-669000161.png

Ci/templates/.travis.yml

有好东西在里面--非常有用的libSegFault.so.trick.

它基本上只运行tox.

1441821-20181106161914191-1826254910.png

1441821-20181106161930089-1471624438.png

1441821-20181106161943127-1251346023.png

1441821-20181106162003028-1828745333.png

1441821-20181106162020459-10907657.png

1441821-20181106162032955-812815023.png

1441821-20181106162046389-780553657.png

1441821-20181106162058110-577814190.png

1441821-20181106162112901-1193698765.png

1441821-20181106162138512-108771561.png

1441821-20181106162152140-282961918.png

1441821-20181106162206943-735436780.png

1441821-20181106162219835-1941700061.png

如果你已经足够耐心通读了全文,你就会注意到:

Travis使用的tox的每一项都在在矩阵里,这使得测试Travis连续性同时,也进行了当地测试。

Tox的环境命令是:clean,check,2.6-1.3,2.6-1.4,...,report.

覆盖测量+环境配置的运行代码是没有安装的(usedevelop=true),最后覆盖能同各种量结合在一起。

没有覆盖+环境配置的代码将进行源分发(sdist),装进虚拟环境中(tox的默认行为),以便及早的发现有关打包的问题。

各种环境中运行的结果最终生成单一报告。

拥有一份在tox.ini中各种环境的完整测试报告优势明显:

你是在本地有干扰的条下并行测试的(除非你的测试需要非常严格的隔离),你还可以用drone.io代替Travis并行运行一切。

你可以在本地为所有东西测量累积覆盖(把所有的环境下的覆盖合并到一起)。

测量覆盖

这种机制-- 一种跟踪时间和多个构建的覆盖范围的好方法,能够自动的把覆盖变化的信息添加到Github Pull Request上。

简单总结

把代码放进src

用tox或detox

有无覆盖两种情况均要测试

为tox.ini和.travis.ini使用生成器脚本

在Travis中用tox运行测试,确保和本地测试条件一致

太复杂?请使用python package template.

还不够清楚?请阅读:Hyneky’s post about the src layout.

也可以查阅:Short list of packaging pitfalls.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值