看了董伟明老师(@董伟明)的《也谈「不要用 Pipenv」》,这篇文章对其中的一些观点做出一些回应和解释。
也看了 Frost Ming 老师(@岂不美哉)的《Pipenv 有什么问题》,很感谢他做出的努力,祝 Pipenv 早日脱离 Kenneth Retiz 的影响,越来越好。
(Kenneth Retiz 下文简称 KR)
KR 有没有借 PyPA 之名来做背书?
所以作者并没有想着用来背书。
我仍然认为 KR 有利用 PyPA 做背书,甚至在误导别人 Pipenv 是 Python 官方(混淆 PyPA 和 Python 官方的概念)推荐的工具。
证据 1
2017 年 8 月 29 号,在 Pipenv 还不够成熟的时候,PyPA 成员 Thea Flowers 创建了一个 PR 要把 Pipenv 添加到 PyPA 的打包教程里,介绍使用 Pipenv 安装和管理依赖(注意这时候 Pipenv 根据教程的内容在 Windows 上是没法正常使用的,具体见 9 月 2 号的这个 issue)。
2017 年 8 月 31 号,Thea Flowers 自己合并了 PR。注意这个教程页面是临时的单独页面,还没有正式放到打包教程的页面里。
2017 年 9 月 1 号,KR 在 Pipenv 的 README 里加了这样一行介绍语:「Pipenv — the officially recommended Python packaging tool from Python.org, free (as in freedom).」(commit)
其中的关键内容翻译过来大概是「官方推荐的 Python 打包工具,来自 Python.org」。
仅仅因为在 PyPA 的打包文档里加入了一个短教程(其中介绍了使用 Pipenv 安装和管理依赖),然后 KR 就在 Pipenv 的介绍里宣传这是「官方推荐」,而注明的官方来源则是「Python.org」,这两个关键词背后的超链接都是 PyPA 打包文档的 Pipenv 介绍。packaging.python.org(PyPA) 和 python.org(Python 官方) 的区别很大,很明显,他清楚两者的区别,但又故意没有表达清楚。
退一步讲,不管他的意图是什么,这样的措辞都会让人以为是 Python 官方推荐的打包工具,尤其是对 PyPA 这个组织不了解的人,看到 Python.org 都会认为是 Python 官方。
证据 2
在 PyCon 2018(五月),KR 在演讲《Pipenv: The Future of Python Dependency Management》里介绍 Pipenv 的卖点的时候,列在第一条的仍然是上面那一句「Officially recommended tool from python.org」:
和在 README 里不同的是,这次在演讲上别人没法去点那个 python.org 的链接去甄别究竟是 python.org(Python 官方) 还是 packaging.python.org(PyPA)。而 KR 在介绍这里的时候没有任何说明,直接说是「来自 Python.org 的官方推荐」。
至于 KR 和 PyPA 或者说和 Thea Flowers 有什么关系?把 Pipenv 的介绍加到打包文档是 Thea Flowers 的个人意愿?还是 PyPA 的 35 个成员全部同意的结果?是什么促使 PyPA 在 Pipenv 还不成熟、甚至教程里的内容没法在 Windows 上正常操作的情况下添加到打包教程里?这些问题我暂时找不到答案。
(注:PyPA 指的是 Python Packaging Authority,一个负责维护 Python 打包相关的库(比如 pip、virtualenv 等)和文档的组织。)
从 0 升到 18 的措辞问题
而所谓的18.X.X是 calver versioning(基于日历的版本)
在上一篇文章里,我引用了一段 HN 上的评论来概括 Pipenv 在推广方式上的问题:
Kenneth Retiz 滥用他在 PyPA 的位置(而且快速把一个实际上是 beta 状态的产品的版本号从 0 升到 18)来暗示 Pipenv 已经非常稳定,受到大力支持并且非常官方,但事实却并不是这样。
这句话的英文原文是:
However, Kenneth abused his position with PyPA (and quickly bumped a what is a beta product to version 18) to imply Pipenv was more stable, more supported and more official than it really was.
其中关于版本的部分是「and quickly bumped a what is a beta product to version 18」,可能是我乱翻译造成了误解……我认为原文里的 18 就是一个夸张的表达方式,把这里的数字换成 100 也可以表达同样的意思(也可能是指 0.3.0 跳到 3.0.1 那次)。换用日期版本号(CalVer)那次看起来没什么问题(11.10.4 -> 2018.05.12),所以我认为这里的 18 和日期版本号没关系。
Lockfile 只要过期就重新生成是合理的吗?
Kenneth Reitz 先是说 lockfile 只要是过期了就总是会被重新生成
这是对的,Pipfile和Pipfile.lock是对应的,当执行pipenv install后改了Pipfile,对应的Pipfile.lock就定会改。错误的是,不应该改那些不相关包的版本: 既然已经是==的了,就表明确定了具体版本呀。
这些问题,其实源于 Pipfile对应依赖在一开始没指定具体版本,也就是Pipfile对标requirements.txt,而Pipfile.lock只是当前环境的一个「快照」,如果Pipfile没有明确版本就用Pipfile.lock里面指定的。
我的主要想法是这样的功能实现是不合理的。Pipenv 在安装一个包的时候默认就使用通配符(*)版本写到 Pipfile 是不合理的设计。这样的设计不符合正常的开发流程和使用习惯。如果我在安装一个包的时候就要明确自己要安装哪个版本,以便在 Pipfile 里固定版本,这样会很不方便,而且让 Pipfile.lock 的存在意义变得很弱。
按照 KR 自己的解释,Pipfile 对标的是 requirements.in,Pipfile.lock 对标的是 requirements.txt:
按照大部分人的理解,Pipfile 是所有不固定版本的高层依赖的列表(unpinned),而 Pipfile.lock 是固定安装时采用版本的详细依赖列表(pinned),用来复现程序具体的依赖环境;除非我主动执行 update 命令更新某个依赖,否则 Pipfile.lock 不应该被改动。但实际的 Pipenv 并不是这样,更新 Pipfile.lock 变成了频繁发生(install/uninstall/update)的默认行为。
Poetry 分析依赖慢
Resolving dependencies… (422.9s)
安装个包7分钟,这… 谁能忍?你们试试把bluelog项目的依赖用poetry add加一遍需要多久?我反正体验不下去了
实际测试安装 Flask-SQLAlchemy,解析依赖花了 42 秒(Windows+代理),没有 7 分钟那么夸张。因为解析依赖的结果会被缓存,我就在另一台 Mac(代理)上也试了一遍,结果只花了 8.3 秒。可能是网络状况的问题?
另外我试了把 Bluelog 的所有依赖一次性安装(Windows+代理),其中解析依赖只花了 16.8 秒(因为解析结果缓存的原因,实际也许会稍久一点):
$ poetry add flask flask-ckeditor flask-mail flask-sqlalchemy flask-wtf flask-moment python-dotenv bootstrap-flask flask-login flask-debu gtoolbar gunicorn psycopg2 flask-migrate Using version ^1.1 for flask Using version ^0.4.3 for flask-ckeditor Using version ^0.9.1 for flask-mail Using version ^2.4 for flask-sqlalchemy Using version ^0.14.2 for flask-wtf Using version ^0.9.0 for flask-moment Using version ^0.10.3 for python-dotenv Using version ^1.0 for bootstrap-flask Using version ^0.4.1 for flask-login Using version ^0.10.1 for flask-debugtoolbar Using version ^19.9 for gunicorn Using version ^2.8 for psycopg2 Using version ^2.5 for flask-migrate Updating dependencies Resolving dependencies... (16.8s)
所以 Poetry 或许没那么糟糕(当然我还没深入使用过)。
星星
虽然不是决定性的,但是对于这Star不到6K的项目来说我是不敢用的
Pipenv 的 Star 的确很多(而且 README、文档甚至代码里到处都是星星✨),KR 可是个营销专家,但项目质量却并没有那么好。反正我现在一看见星星和蛋糕就有点头疼。
✨?✨
另外,顺便说一句,pip(5627)、virtualenv(3189)和 setuptools(883) 的 Star 数量都没到六千……
好吧,我承认最后这两段是在抬杠 :D