作者:YunfengWang
来源:https://vra.github.io/2023/05/17/rye-intro
Rye[1] 是 Flask 的作者 Armin Ronacher[2] 最近推出的一个实验性质的 Python 包管理系统,目的是解决 Python 包管理目前面临的工具链碎片化的问题。
大家知道,Python 目前的包管理系统很多,包括 poetry、pip、pipenv、pyenv、venv、virtualenv、pdm、hatch 等等,它们都是优秀的工具,提出时都是解决了一定的问题,但没有哪个工具能够做到主流,因此也增加了系统的碎片化程度。
另一方面,conda 等工具能提供不同版本的 Python,管理不同的环境,但每个环境的 Python 不是共享的,环境创建一多,环境目录就变得很大,且内部机制很不透明,有时也会遇到冲突没法解决的问题。
另一方面,Python 在 Linux/macOS 上的安装也面临一些问题,例如用包管理器安装的 Python 和用户手动安装的 Python 有的时候会混淆,导致一些混乱,例如在 Fedora 上,用 pip install 安装包可能会导致系统的包管理命令 dnf 出错。PEP 668[3] 尝试对这些问题给出一个解决方案,但也需要不同的系统来支持,目前看还任重道远。
由于 Armin 也是一个 Rust 开发者,而 Rust 基于标准化的 rustup 和 cargo 两个工具,配合配置文件来进行包管理,目前做的比较好,没有 Python 面临的碎片化问题。受 Rust 的启发,作者提出了 Rye,并且期望能够启发 Python 社区提出类似 Rust 的标准包管理工具。
具体来说,Rye 提出了一些解决这些问题的思路:
但同时也有一个问题:rye 会不会是另一个做不到主流的 Python 包管理系统,从而进一步增加 Python 包管理的碎片化呢?作者也有这个考虑,因此写了一个讨论帖 Should Rye Exist?[4] 来讨论这个问题,同时关于 Rye 的设计初衷,可以参考这里[5]作者的思考。
个人观点:Rye 的出现给 Python 社区引入了一些新鲜的解决现有问题的思路。使用 Rye 一段时间后,发现至少使用 standalone 的 Python 版本是一个解决冲突的好的方式。通过几个简单的命令来解决版本管理的问题是比较直观的,提出 Rye 应该是利大于弊的,也就是有益程度大于碎片化增加的程度。
总之不管是 PEP-668 中标记版本管理是系统的还是 Python 的,还是 PEP 711[6] 来单独下发 Python 解释器二进制文件,还是 Rye 的出现,都是 Python 社区意识到 Python 包管理问题的严重性,进而做出的一些有益尝试。期待在未来,有更标准化的工具,Python 的开发也更容易。
下面将对 Rye 的安装和使用进行简单介绍。
Rye 是基于 Rust 开发的,而 Rust 有标准的包安装工具 cargo,Rust 编译器和 cargo 都需要用 rustup 来安装,因此安装预编译的 Rye 包需要先安装 rustup:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
执行完后,重启 Shell,输入 cargo -V,如果不报错,说明安装成功。
有了 cargo 后,使用下面的命令安装 Rye:
cargo install --git https://github.com/mitsuhiko/rye rye
通过命令行执行 rye -h 来判断 Rye 是否安装成功。
同时可以将 $HOME/.rye/shims 添加到环境变量 PATH 中,这样打开 Shell 后运行 python 就用的是 Rye 安装到 standalone Python,否则你需要用 rye run python 来启用 Rye 的 Python 解释器。
更新 Rye 到最新版:
rye self update
删除 Rye:
cargo uninstall rye
使用 rye init project-name 来创建一个 Rye 项目目录
rye init test_ryecd test_ryetree
输出如下:
├── .git├── .gitignore├── .python-version├── README.md├── pyproject.toml└── src └── test_rye └── __init__.py
可以看到创建了. git 目录, .gitignore 文件,README.md,配置文件 pyproject.toml 和一个示例的源码文件 src/test_rye/__init__.py。
为了固定开发环境,我们可以利用 rye pin python-version 来固定 Python 的版本,例如 rye pin cpython@3.10.11 会将 Python 版本固定为 3.10.11。
# cpython@可以省略rye pin cpython@3.10.11rye pin 3.10.11
由于默认使用的 Python 版本是 Cpython 的,因此在执行 rye 命令时可以将 Cpython@ 前缀省去。
注意 rye pin 命令并不立即改变 Python 的版本,只是修改配置文件. python-version,在 rye sync 执行时才进行实际的修改。
可以多次执行 rye pin 来调整 Python 的版本。
然后执行 rye sync 来同步配置,具体来说,第一次执行这个命令的时候,Rye 会下载一个单独的 Python 解释器,放置到 $HOME/.rye/py 目录下,链接到项目的. venv 目录下,因此同一个 Python 版本在磁盘上只有一份,这与 conda 是不同的。
更一般地,可以使用 rye toolchain 来查看、拉取和删除 Python 版本。
rye toolchain list 用来显示所有已经安装的 Python 版本:
rye toolcahin list
输出:
cpython@3.11.3 (/Users/yunfeng/.rye/py/cpython@3.11.3/install/bin/python3)cpython@3.11.1 (/Users/yunfeng/.rye/py/cpython@3.11.1/install/bin/python3)cpython@3.10.11 (/Users/yunfeng/.rye/py/cpython@3.10.11/install/bin/python3)cpython@3.10.9 (/Users/yunfeng/.rye/py/cpython@3.10.9/install/bin/python3)
rye toolchain list --include-downloadable 会列出所有可以下载的 Python 版本:
rye toolchain list --include-downloadable
输出:
cpython@3.10.8 (downloadable)cpython@3.10.7 (downloadable)cpython@3.10.6 (downloadable)cpython@3.10.5 (downloadable)cpython@3.10.4 (downloadable)cpython@3.10.3 (downloadable)cpython@3.10.2 (downloadable)cpython@3.10.0 (downloadable)...
注意已经下载的 Python 版本不在这个输出中。
rye toolchain fetch(简写为 rye fetch) 可以直接拉取某个 Python 版本:
rye toolchain fetch 3.8.16
rye toolchain remove 可以删除某个 Python 版本:
rye toolchain remove 3.8.16
可以通过 rye add package-name 来安装像 numpy 等第三方,这个命令支持安装 GitHub 和本地的包,一些示例的用法如下:
rye add numpy# 同时安装几个包rye add six easydict# 设置安装包的版本rye add "Flask>=2.0"# 只在development环境添加包rye add --dev black# 添加github上的包rye add Flask --git=https://github.com/pallets/flask# 添加本地目录的包rye add My-Utility --path ./my-utility
同样的,rye add 并不会实际安装包,只会修改配置文件 pyproject.toml 中的 dependencies 项,等执行 rye sync 的时候才真正安装。
我自己探索的 Rye 工作流大概是这样:
需要注意的是,Rye 只负责依赖管理,具体的调试代码工作,还需要自己来进行,使用你熟悉的代码测试方式就可以了。
额外补充一下,可以使用 rye shell 来打开一个新的启用了 Rye Python 的 Shell 来进行代码调试。
某些 python 包除了包含 Python 源码外,还包含一些命令行工具,Rye 称这些工具为 global tool ,因为它们不是在某个环境中才能使用,而是全局可使用的。这些工具可以用 rye install package-name 来安装,例如:
rye install black
使用方式为 rye run tool-name:
rye run black -h
这些包都存放在 $HOME/.rye/shims 目录下。 如果要删除 global tool,可以使用 rye uninstall:
rye uninstall black
[1]Rye: https://mitsuhiko.github.io/rye
[2]Armin Ronacher: https://github.com/mitsuhiko
[3]PEP 668: https://peps.python.org/pep-0668
[4]Should Rye Exist?: https://github.com/mitsuhiko/rye/discussions/6
[5]这里:
https://mitsuhiko.github.io/rye/philosophy
[6]PEP 711: https://peps.python.org/pep-0711