向一个 “核心 Python”迈进
收藏


一个最小标准库的人生改变魔法


受Amber Brown上个月在Python语言峰会上的演讲的鼓舞,Christian Heimes继续了他早期的精简Python标准库的工作,并创建了一个适当的Python增强建议PEP 594,用于从标准库中删除明显过时的和未维护的陈旧库。


PEP 594对于Python来说是一个好消息,特别是对于它的标准库的维护者来说,他们现在要处理的东西的范围有所减少。对这个PEP中列出的将要废弃或删除[1]的模块进行一个简短的了解是很有启发性的。Python标准库包含了大量有用的模块,但是它也隐藏了一个十足的代码墓地,就像一个陈旧的高耸纪念碑,随时可能会倒向它的维护者。


然而,我认为此PEP可能是从错误的方向来处理这个问题的。目前,标准库与CPython运行时一起维护,并由CPython运行时的维护者维护。标准库中很大一部分可能只是对某些人有用。在前面提到的PEP中,你可以看到这个逻辑在为colorsys模块辩护:为什么不删除它?“这个模块可以在坐标系统之间转换CSS颜色。(它)不会给核心开发带来维护开销。”

在互联网的早期,网络并不是随处可见,网速也非常糟糕。那时在Python的安装包中预装足够多的库是有帮助的,这样,当你开始学习时,CD-ROM上预先打包的Python二进制文件就可以直接运行,而不必依赖互联网。


然而,在今天,你只需通过一个pip install命令就可以安装在坐标系统之间转换颜色所需的模块。更大的核心解释器只是会在你开始之前让你等待更多的时间(下载、安装都会变慢)。


你为什么不审查我的PR?


那么让我们来看看这个断言:像colorsys这样一个小模块是否会“给核心开发带来维护开销”?


核心维护者已经做了足够的工作来维护庞大而古老的C代码库,即CPython本身。正如Mariatta在她的North Bay Python主题演讲中所说,核心开发人员得到的最常见的问题是“为什么你还没有查看我的PR?”那答案呢?当你不关心一些PR时,你很容易就不会去看它们。这来自于一个关于成为一个核心开发者意味着什么的演讲!


有人可能会问,Twisted是否也有同样的问题。Twisted也是松散连接模块的一个大集合;一种用于网络的标准库。SSH、IMAP、HTTP、TLS等的客户端和服务器都要挤进一个包吗?

我不得不回答:是的。Twisted是庞大而单一的,因为它可以追溯到与CPython类似的历史时期,在那个时期,安装东西非常复杂。所以我对CPython的困境既同情又感同身受。


在某种程度上,Twisted中的每个子项目都应该成为一个独立的项目,拥有自己的存储库、CI、网站,当然还有自己更专注的维护者。我们已经在慢慢地划分项目,在那里我们可以找到一个自然的边界。一些从Twisted开始的东西,比如constantly和 incremental,已经被分割出来;deferred 和 filepath也正在分割中。组织中吸收的其他项目将继续独立存在,比如klein和treq。当我们弄清楚如何为它们中的每一个减少设置和维护CI及发布基础设施的开销时,我们将做更多这样的工作。


但是,对于这个项目来说,我们的整体性是最紧迫的问题,甚至是一个严重的问题吗?我们来对其进行量化。


在撰写本文时,我们的审核队列中有5个突出的未审核的Twisted合并申请。审核一个ticket需要花费的平均时间大约是四天半[2]。我们的审核队列中最早的ticket可以追溯到4月22日,这意味着我们最早的未审核的PR提交不到两个月。


要找到足够的维护人员和足够的时间来响应合并申请总是很困难的。主观上来说,我有时确实会觉得“你为什么不审查我的合并申请?”这是一个我们仍然经常会遇到的问题。在这个问题上,我们并不总是做得很好,但总而言之,我们在设法做。在一个糟糕的月份,这个队列在0天(最低)和25天(左右)之间徘徊。


与这些数字相比,核心CPython的表现如何呢?


查看一下CPython基于关键字的审查队列,我们就可以看到目前有429个ticket等待审查。自2018年2月2日以来,等待审查的最早的PR一直没有动过,至今已有近500天之久了。


有多少是解释器问题,有多少是标准库问题?显然,审查延迟是一个问题,但是删除标准库会有帮助吗?


为了进行一个快速和非常不科学的估计,我扫描了上面查询中的第一个(最远的)PR页面。根据我的主观评价,在这个有25个PR的页面中,14个是关于标准库的,10个是关于核心语言或解释器代码的;一个是一个小的文档问题,但也并不完全适用。如果我可以冒险基于这个比例进行非常粗略的估计,那么大约一半未审阅的PR可能在标准库代码中。


所以,CPython核心团队需要停止维护标准库的第一个原因是他们实际上没有时间去维护标准库。或者换句话说:他们没有在维护它,剩下的就是承认这一点,并开始对标准库进行拆分。


确实,CPython上所有开放的PR没有一个是关于colorsys[3]的。实际上,它不会给核心开发带来维护开销,而核心开发却给它增加了维护开销。如果我想要更新colorsys模块使其更加现代化——也许是为了拥有一个Color对象而不是一组免费函数,也许是为了支持整数颜色模型——我可能需要等待500天,或者更久,才能得到一个审查结果。


因此,标准库中的代码更难更改,这意味着其用户对它的代码贡献积极性更低。CPython异常不频繁的发布也减慢了库代码的开发,并降低了用户反馈的有用性。标准库中的几乎所有模块都在标准库之外拥有活跃地维护替代方案,这绝非偶然,这也不是标准库维护者的失败。这样整个过程就会产生停滞,除了标准库中最常用的部分外,而这正是该PEP所做的事情。


新环境,新需求


也许更重要的是,将CPython与其本身的标准库绑定在一起,这样做明显只考虑到了CPython自己以及它支持的一些用例,而忽略了Python的一些其他实现的需求。


一个接一个的播客和keynote告诉我们,为了保持成功和扩展,Python需要向新的领域发展:尤其是web前端,但也包括移动客户端、嵌入式系统和控制台游戏。


这些环境需要以下的一个或两个:


  • 一个完全不同的运行时,比如Brython或MicroPython

  • 一个经过修改、精简的标准库版本,其中省略了大部分内容


在所有这些情况下,确定从标准库中删除了哪些模块是一个难点。只有通过反复尝试才能发现它们,值得注意的是,这与确定Python应用程序中的依赖关系的标准过程完全不同。没有install_requires申明语句可以让你放在你的setup.py中,来指明你的库使用了一个标准库模块,而目标Python运行时可能会由于空间的限制可能会忽略该模块。


即使你只在Linux安装中使用标准python,你也可能会遇到这个问题。即使是服务器级和桌面级Linux发行版也同样需要一个更小的核心Python包,因此它们已经随意地分解了标准库。这可能会打破许多python代码库的预期,并导致甚至pip install都无法工作的bug。


把它全部拿出来


“我们每天只做一点的建议怎么样?虽然它听起来很有说服力,但请不要被愚弄。你似乎永远不会完成的原因恰恰是因为你一次只整理一点点。[...]成功的终极秘密是这样的:如果你一次整理完,而不是一点一点的整理,那你可以显著地改变你的思维定势。”

— Kondō, Marie.  《怦然心动的人生整理魔法》(段落15-16)


虽然标准库的增量瘦身是朝着正确方向迈出的一步,但是增量更改只能让我们走到这一步。正如Marie Kondō所说, 当你真的想整理时,第一步是把所有东西都拿出来,这样你就可以真正看到所有东西,并只放回你所需要的东西。


是时候感谢那些没有让人怦然心动的模块并将它们送走了。


我们需要一个只包含最绝对地最小库的“内核”版本的Python,以便所有的实现可以达成一致的核心基准,给你一个“python”,和应用程序,即使是那些想运行在web浏览器或微控制器上的应用,也可以简单的使用requirements.txt来声明它们额外的需求。


现在,在一些商业环境中,向requirements.txt添加东西是一个充满不愉快的官僚过程,并且在这些地方,大型标准库似乎更有吸引力。但是,“标准库”是谁来定义?Python安装的二进制文件里包含哪些库,完全可以自己定义。


因此,对于一些CPython二进制发行版(可能甚至是官方发行版)来说,仍然从PyPI中提供更广泛的模块选择可能确实很有用。即使对于普通用户来说,为了使用它进行开发,你至少也需要足够的标准库,以便pip能够引导自己去安装所需的其他模块!


现在的情况是,pip与Python一起发布,但不在CPython存储库中维护。默认的Python二进制安装程序附带的是什么。与CPython存储库中开发的是什么,或者单个的源码包中为解释器附带了什么相比,已经是一个独立的问题了。


为了使用Linux,你需要带有大量附加程序的可引导媒介。这并不意味着Linux内核本身位于一个巨大的存储库中,在这个存储库中,一个正常运行的Linux服务器所需的数百个应用程序都由一个团队维护。Linux内核项目非常有价值,但是使用它的运行操作系统是由Linux内核和各种单独维护的库和程序组合构建而成的。


结论


“内置电池”的理念在创建之初就是非常适合的: 它是一个助推火箭,将Python偷偷带入编程公众的想象中。然而,随着开放源码和Python打包生态系统的成熟,这种策略还没有成熟,就像任何助推器一样,我们必须让它回到地球上,以免它将我们拖下水。


新的Python运行时、新的部署目标和新的开发人员受众都为Python社区提供了前所未有的巨大机会。


但是要做到这一点,我们需要一个更新的、更精简的、没有负担的“内核”Python。我们需要把整个标准库扔到地上,只添加回我们需要的最小的部分,这样我们就可以知道什么是真正必要的,什么是最好要有的。


我希望我至少说服了你们中的一些人: 我们需要一个内核Python。


现在: 谁想来编写这个PEP?


致谢


感谢Jean-Paul Calderone、Donald Stufft、Alex Gaynor、Amber Brown、Ian Cordasco、Jonathan Lange、Augie Fackler、Hynek Schlawack、Pete Fein、Mark Williams、Tom Most、Jeremy Thurgood和Aaron Gallagher对本文早期草稿的反馈和勘误。当然,任何错误都是我自己的。


  1. sunau, xdrlib, 和 chunk是我个人最喜欢的库。

  2. 好吧,好吧,被你发现了,这个平均值是102天。

  3. 好吧,事实证明,其中一个是关于colorsys的,但它是Alex Gaynor在审查了这篇文章的草稿后提交的一个文档修复,所以我不认为它真的很重要。


英文原文:https://glyph.twistedmatrix.com/2019/06/kernel-python.html
译者:测试