Pipenv vs Poetry

20th August 2020 at 2:19pm
Python: Dependency and Environment Management Python: Packaging

Pipenv 和 poetry 在功能上是非常类似的。

配置文件

Pipenv 使用自定义的 PipfilePipfile.lock 来管理文件。

Poetry 使用 标准化的pyproject.toml 和自定义的 JSON 文件 peotry.lock

Deterministic Builds

Deterministic Builds 即是确定性的构建,即是每个人安装项目依赖时,都会得到一样的 Python 库的依赖。这是靠 lock 文件实现的。

Peotry 在这方面的设计明显好过 Pipenv:

  • peotry install 不带参数时默认使用 lock 文件中定义的依赖;pipenv 则是使用非 lock 文件中的依赖
    • pipenv 在这方面表现较差。从 lock 文件进行安装,居然不是一开始就搭载上的功能,而是后面用户提 issue 后加的,而且居然用了一个 --ignore-pipfile 这么奇怪的名称,来给应该是一等公民的 deterministic builds 功能使用
  • peotry install 一个库时,默认会在 pyproject.toml 中纪录这个库最新版本的 tilde requirement,这是避免后面破坏性升级的好实践;Pipenv 会使用 wildcard (*),意味着后面你可能一不小心把依赖库升级到新版本引发不兼容
  • pipenv install 一个库时,还会把 Pipfile 中其他的库也升级到最新版本,并写进 Pipfile.lock 中。虽然提供了 --keep-outdated 参数,但是这个默认行为感觉过于激进。结合上一条描述的 * 作为库的默认版本范围,这个行为很容易 break things

依赖解析

Pipenv 的依赖解析做得不够好,有些时候项目的依赖是有解的,但是 Pipenv 解不出来。sdispater/poetry 上有一个例子。

功能差异

  • Peotry 即可以做 Python 应用的依赖管理(比如你的 Web 项目),也可以做 Python 库的;而 Pipenv 只能做 Python 应用的
  • Peotry 支持上传 PyPI
  • Peotry 可以替代 setup.py,是更统一的解决方案;而 Pipenv 不能

个人体验

从 API 设计和一些行为看,pipenv 不像是质量优良的产品,用的过程中也遇到大大小小的 bug。比较难接受的是,在宣传上几乎是被认为 Python 项目依赖管理的最佳实践,但是却不是质量足够高的产品。

实际使用时 pipenv install 中的 --deploy 参数,在字面含义上难以理解,同时执行起来行为又不如所描述的。

Peotry 个人使用得不多,还没遇到什么坑。但是觉得 poetry init 这个生成脚手架的功能并不是很合适,只生成一个 pyproject.toml 会更好。

参考