Rust 開發的高性能 Python 包管理工具,可替換 pip、pip-tools 和 virtualenv

最近,我在 Python 潮流週刊 中分享了一個超級火爆的項目,這還不到一個月,它在 Github 上已經拿下了 8K star 的亮眼成績,可見其受歡迎程度極高!國內還未見有更多消息,我趁着週末把一篇官方博客翻譯出來了,分享給大家。

作者:@charliermarsh

譯者:豌豆花下貓@Python貓

英文:uv: Python packaging in Rust (https://astral.sh/blog/uv)

聲明:本翻譯是出於交流學習的目的,爲便於閱讀,部分內容略有改動。轉載請保留作者信息。

摘要

uv 是一個極其快速的 Python 包安裝器和解析器,用 Rust 編寫,旨在作爲 pip 和 pip-tools 工作流的替代品。

它代表了我們追求“Python 的 Cargo”的里程碑:一個全面、快速、可靠且易於使用的 Python 項目和包管理器。

作爲此次發佈的一部分,我們還將接管 Rye,這是 Armin Ronacher 開發的一個實驗性 Python 打包工具。我們將維護它,直到我們將 uv 擴展成統一的後繼項目,以實現我們對 Python 打包的共同願景。


在 Astral,我們爲 Python 生態系統構建高性能的開發工具。我們最出名的是 Ruff,一個極其快速的 Python linter 和格式化工具。(譯註:對 Ruff 的介紹 性能最快的代碼分析工具,Ruff 正在席捲 Python 圈!

今天,我們發佈了 Astral 工具鏈中的下一個工具:uv,一個用 Rust 開發的高性能的 Python 包解析器和安裝器。

圖注:使用熱緩存來解析(左)和安裝(右)Trio 依賴項,以模擬重新創建虛擬環境或向現有項目添加依賴項

uv 旨在作爲 pip、pip-tools 和 virtualenv 的直接替代品,現在就可以用於生產環境中那些圍繞這些工作流構建的項目。

產品原則

與 Ruff 一樣,uv 的實現也遵循我們的核心產品原則:

  1. 癡迷於高性能

在上述基準測試中,uv 在沒有緩存的情況下比 pip 和 pip-tools 快 8-10 倍,而在有熱緩存的情況下(例如,重新創建虛擬環境或更新依賴項),則快 80-115 倍。

uv 使用全局模塊緩存來避免重新下載和構建依賴項,並在支持的文件系統上利用 Copy-on-Write 和硬鏈接來最小化磁盤空間使用。

  1. 優化以便於採用

儘管我們對 Python 打包的未來有着宏大的願景,但 uv 的初始版本聚焦於支持我們 uv pip 接口背後的 pip 和 pip-tools,使其可以零配置地被現有項目所採用。

相似地,uv 可以“僅僅”當作一個解析器(uv pip compile 鎖定你的依賴項),“僅僅”當作一個虛擬環境創建器(uv venv),“僅僅”當作一個包安裝器(uv pip sync),等等。它既是統一的,又是模塊化的。

  1. 簡化的工具鏈

uv 作爲一個單一的靜態二進制文件發佈,能夠替代 pip、pip-tools 和 virtualenv。uv 沒有直接的 Python 依賴,因此你可以跟 Python 本身分別安裝,避免了在多個 Python 版本(例如,pip vs. pip3 vs. pip3.7)之間選擇 pip 安裝程序。

安裝使用

雖然 uv 將演變成一個完整的 Python 項目和包管理器(“Cargo for Python”),但像pip-tools 這樣較狹窄的聚焦範圍,讓我們得以解決構建此類工具所涉及的低級問題(如包安裝),同時立即提供有用的東西,最小化社區的使用障礙。

你可以通過我們的獨立安裝程序安裝 uv,或者從 PyPI 安裝。

使用 curl:

curl -LsSf https://astral.sh/uv/install.sh | sh

對 Windows:

powershell -c "irm https://astral.sh/uv/install.ps1 | iex"

使用 pip 或 pipx:

pip install uv
pipx install uv

uv 能滿足你對現代 Python 打包工具的所有期望:可編輯安裝、Git 依賴項、URL 依賴項、本地依賴項、約束文件、源碼分發、自定義索引等,所有這些都設計成與你現有的工具無縫兼容。

uv 支持 Linux、Windows 和 macOS,並已針對公共的 PyPI 索引進行了大規模測試。

本文首發於 Python貓,博客:https://pythoncat.top/posts/2024-03-05-uv

即插即用的兼容性 API

這個初始版本主要實現了 uv 的pip 命令。對於使用過 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,它看起來將更像 Rye、Cargo 或 Poetry。(想象一下 uv runuv build 等等)

uv 也可以通過uv venv 作爲虛擬環境管理器使用。它比python -m venv 快大約 80 倍,比virtualenv 快 7 倍,且不依賴於 Python。

圖注:創建一個虛擬環境,有(左)和沒有(右)pip 及 setuptools 種子包

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 允許依賴項“覆蓋”。 uv 通過覆蓋(-o overrides.txt)將 pip 的“約束”概念向前推了一步,允許用戶通過覆蓋包的聲明依賴項來引導解析器。覆蓋爲用戶提供了一個逃生艙口,用於解決錯誤的上限和其他錯誤聲明的依賴項。

在當前形式下,uv 並不適合所有項目。pip 是一個成熟且穩定的工具,支持非常廣泛的場景,並且專注於兼容性。雖然 uv 支持 pip 的大部分功能,但它缺乏對一些傳統特性的支持,比如 .egg 分發。

同樣,uv 目前還不支持生成與平臺無關的鎖定文件。這與 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 的開發做出貢獻的人。其中最重要的是 pubgrub-rs 的維護者 Jacob Finkelman 和 Matthieu Pizenberg。uv 使用了 PubGrub 作爲其底層版本解析器,我們感謝 Jacob 和 Matthieu 在過去對 PubGrub 所做的工作,以及他們作爲合作者對整個項目的關鍵助力。

我們還要感謝那些啓發了我們的打包項目,尤其是 Cargo,以及來自 JavaScript 生態的 Bun、Orogene 和 pnpm,以及來自 Python 生態的 Posy、Monotrail 和 Rye。特別感謝 Armin Ronacher 與我們合作完成這項工作。

最後,我們還要感謝 pip 的維護者們以及更廣泛的 PyPA 的成員,感謝他們爲使 Python 打包成爲可能所做的所有工作。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章