TL;DR: uv 是一个用 Rust 编写的极速 Python 包安装器和解析器,旨在完全取代 pip
和 pip-tools
工作流。
uv 代表着我们在追求“Python 版 Cargo”方面的一个里程碑:一个全面、快速、可靠且易用的 Python 项目和包管理器。
作为本次发布的一部分,我们还将接管 Rye,这是 Armin Ronacher 开发的一个实验性 Python 包管理工具。我们将在把 uv 发展成一个统一的后续项目时,继续维护 Rye,以实现我们对 Python 包管理的共同愿景。
在 Astral,我们为 Python 生态系统构建高性能开发者工具。我们最知名的产品是 Ruff,一个极速的 Python Linter(代码检查器)和 Formatter(代码格式化工具)。
今天,我们发布 Astral 工具链中的下一个工具:uv,一个用 Rust 编写的极速 Python 包解析器和安装器。
在Trio依赖项上,使用热缓存(warm cache)进行解析(左)和安装(右),模拟重新创建虚拟环境或向现有项目添加依赖项的情形(来源)。
在Trio依赖项上,使用热缓存(warm cache)进行解析(上)和安装(下),模拟重新创建虚拟环境或向现有项目添加依赖项的情形(来源)。
uv 被设计为 pip
和 pip-tools
的即插即用替代品,现在就可以用于围绕这些工作流构建的项目中。
与 Ruff 类似,uv 的实现也遵循我们的核心产品原则:
- 对性能的极致追求。 在上述基准测试中,uv 在未缓存时比
pip
和pip-tools
快 8-10 倍,在热缓存(warm cache)情况下运行时(例如,重新创建虚拟环境或更新依赖项)更是快 80-115 倍。uv 使用全局模块缓存来避免重复下载和重新构建依赖项,并在受支持的文件系统上利用写时复制(Copy-on-Write)和硬链接(hardlinks)来最大限度地减少磁盘空间使用。 - 为普及性而优化。 虽然我们对 Python 包管理的未来抱有远大抱负,但 uv 的初始版本专注于通过我们的
uv pip
接口支持pip
和pip-tools
的 API,使其无需任何配置即可被现有项目使用。同样,uv 也可以仅用作一个解析器(uv pip compile
用于锁定您的依赖项)、一个虚拟环境创建器(uv venv
)、一个包安装器(uv pip sync
)等等。它既统一又模块化。 - 简化的工具链。 uv 作为一个独立的静态二进制文件发布,能够替代
pip
、pip-tools
和virtualenv
。uv 没有直接的 Python 依赖,因此您可以独立于 Python 本身进行安装,避免了在多个 Python 版本之间管理pip
安装(例如,pip
、pip3
与pip3.7
)的需求。
虽然 uv 将发展成为一个完整的 Python 项目和包管理器(一个“Python 版 Cargo”),但更窄的 pip-tools
范围使我们能够解决构建此类工具所涉及的底层问题(如包安装),同时推出立即可用、普及门槛极低的产品。
uv 支持现代 Python 包管理工具所应具备的一切功能:可编辑安装、Git 依赖项、URL 依赖项、本地依赖项、约束文件、源分发、自定义索引等,所有这些都旨在与您现有工具实现即插即用兼容。
uv 支持 Linux、Windows 和 macOS,并已针对公共 PyPI 索引进行了大规模测试。
即插即用兼容的 API #
此初始版本专注于我们称之为 uv 的 pip
API。对于过去使用过 pip
和 pip-tools
的人来说,它将很熟悉:
- 不再是
pip install
,而是运行uv pip install
,以从命令行、requirements 文件或pyproject.toml
安装 Python 依赖项。 - 不再是
pip-compile
,而是运行uv pip compile
,以生成锁定的requirements.txt
文件。 - 不再是
pip-sync
,而是运行uv pip sync
,以将虚拟环境与锁定的requirements.txt
同步。
通过将这些“低层级”命令归入 uv pip
之下,我们在 CLI 中为未来计划提供的更具“主见”的项目管理 API 保留了空间,这些 API 将更像 Rye、Cargo 或 Poetry。(想象一下 uv run
、uv build
等命令。)
uv 也可以通过 uv venv
用作虚拟环境管理器。它比 python -m venv
快约 80 倍,比 virtualenv
快 7 倍,且不依赖于 Python。
uv 的虚拟环境符合标准,可与其他工具互换使用——没有锁定或定制。
从头构建我们自己的包管理堆栈也为新功能提供了空间。例如:
- uv 支持备选解析策略。 默认情况下,uv 遵循标准的 Python 依赖解析策略,即优先选择每个包的最新兼容版本。但通过传递
--resolution=lowest
参数,库作者可以针对其依赖项的最低兼容版本测试其包。(这类似于 Go 的最小版本选择。) - uv 允许针对任意目标 Python 版本进行解析。 虽然
pip
和pip-tools
总是针对当前安装的 Python 版本进行解析(例如,在 Python 3.12 下运行时生成 Python 3.12 兼容的解析结果),但 uv 接受--python-version
参数,使您即使在较新版本下运行,也能生成 Python 3.7 兼容的解析结果。 - uv 允许依赖项“覆盖”(overrides)。 uv 通过覆盖(overrides)功能(
-o overrides.txt
)将 pip 的“约束”(constraints)概念更进一步,它允许用户通过覆盖包的声明依赖项来引导解析器。覆盖为用户提供了一个应急方案,用于解决错误的上限和其他声明不正确的依赖项。
以其当前形式,uv 不适合所有项目。pip
是一个成熟稳定的工具,广泛支持各种用例,并注重兼容性。虽然 uv 支持 pip
接口的大部分功能,但它缺少对其某些旧版功能的支持,例如 .egg
分发。
同样,uv 尚不支持生成平台无关的 lockfile(锁定文件)。这与 pip-tools
一致,但与 Poetry 和 PDM 不同,这使得 uv 更适合围绕 pip
和 pip-tools
工作流构建的项目。
对于深入包管理生态系统的人来说,uv 还包括符合标准的 Rust 实现,涵盖 PEP 440 (版本标识符)、PEP 508 (依赖项指定符)、PEP 517 (一个与构建系统无关的构建前端)、PEP 405 (虚拟环境) 等规范。
“Python 版 Cargo”:uv 和 Rye #
uv 代表着我们在追求“Python 版 Cargo”方面的一个中间里程碑:一个极速、可靠且易用的统一 Python 包和项目管理器。
想象一下:一个单一的二进制文件,能够引导您的 Python 安装,并为您提供高效使用 Python 所需的一切,它不仅捆绑了 pip
、pip-tools
和 virtualenv
,还包括 pipx
、tox
、poetry
、pyenv
、ruff
等工具。
Python 工具的使用体验可能缺乏信心:搭建新项目或现有项目需要大量工作,命令会以令人困惑的方式失败。相比之下,在 Rust 生态系统中工作时,您相信工具会成功。Astral 工具链旨在将 Python 从缺乏信心的体验带向充满信心的体验。
这种对 Python 包管理的愿景与 Rye 所提出的愿景不谋而合,Rye 是 Armin Ronacher 开发的一个实验性的项目和包管理工具。
与 Armin 交流后,很明显我们的愿景高度契合,但要实现这些愿景,需要对基础工具进行大量投入。例如:构建此类工具需要一个极速、端到端集成、跨平台的解析器和安装器。在 uv 中,我们已经构建了这些基础工具。
我们认为这是一个难得的合作机会,可以避免 Python 生态系统的碎片化。因此,与 Armin 合作,我们很高兴能够接管 Rye。 我们的目标是将 uv 发展成为一个可用于生产的“Python 版 Cargo”,并在时机成熟时,提供从 Rye 到 uv 的平滑迁移路径。
在此之前,我们将继续维护 Rye,将其底层迁移为使用 uv,更广义地说,将其视为我们正在构建的最终用户体验的实验性测试平台。
虽然合并项目会带来其自身的挑战,但我们致力于在 Astral 旗下构建一个单一、统一的工具,并随着 uv 发展成为一个合适且全面的后续项目,支持现有的 Rye 用户。
我们的路线图 #
本次发布后,我们的首要任务是支持用户考虑使用 uv,重点关注提高跨平台的兼容性、性能和稳定性。
在此基础上,我们将着手将 uv 扩展为一个完整的 Python 项目和包管理器:一个单一的二进制文件,为您提供高效使用 Python 所需的一切。
我们为 uv 制定了宏伟的路线图。但即使以其当前形式,我认为它也会给 Python 带来截然不同的体验。我希望您能尝试一下。
致谢 #
最后,我们衷心感谢所有直接或间接为 uv 开发做出贡献的人。其中最重要的是 Jacob Finkelman 和 Matthieu Pizenberg,他们是 pubgrub-rs 的维护者。uv 使用 PubGrub 作为其底层版本解析器,我们感谢 Jacob 和 Matthieu 过去在 PubGrub 上所做的工作,以及他们在整个项目过程中作为合作者与我们互动的方式。
我们还要感谢那些在包管理领域激励了我们的项目,特别是 Cargo,以及来自 JavaScript 生态系统的 Bun、Orogene 和 pnpm,以及来自 Python 生态系统的 Posy、Monotrail 和 Rye。特别感谢 Armin Ronacher 在此项工作上与我们合作。
最后,我们还要感谢 pip 的维护者以及更广泛的 PyPA 成员,感谢他们为使 Python 包管理成为可能所做的一切工作。