用 Rust 開(kāi)發(fā)的 Python 包管理工具,可替換 pip、pip-tools 和 virtualenv
在 Astral,我們?yōu)?Python 生態(tài)系統(tǒng)構(gòu)建高性能的開(kāi)發(fā)工具。我們最出名的是 Ruff,一個(gè)極其快速的 Python linter 和格式化工具。(譯注:對(duì) Ruff 的介紹 性能最快的代碼分析工具,Ruff 正在席卷 Python 圈!)
今天,我們發(fā)布了 Astral 工具鏈中的下一個(gè)工具:uv,一個(gè)用 Rust 開(kāi)發(fā)的高性能的 Python 包解析器和安裝器。
圖片
圖注:使用熱緩存來(lái)解析(左)和安裝(右)Trio 依賴(lài)項(xiàng),以模擬重新創(chuàng)建虛擬環(huán)境或向現(xiàn)有項(xiàng)目添加依賴(lài)項(xiàng)
uv 旨在作為 pip、pip-tools 和 virtualenv 的直接替代品,現(xiàn)在就可以用于生產(chǎn)環(huán)境中那些圍繞這些工作流構(gòu)建的項(xiàng)目。
產(chǎn)品原則
與 Ruff 一樣,uv 的實(shí)現(xiàn)也遵循我們的核心產(chǎn)品原則:
- 癡迷于高性能
在上述基準(zhǔn)測(cè)試中,uv 在沒(méi)有緩存的情況下比 pip 和 pip-tools 快 8-10 倍,而在有熱緩存的情況下(例如,重新創(chuàng)建虛擬環(huán)境或更新依賴(lài)項(xiàng)),則快 80-115 倍。
uv 使用全局模塊緩存來(lái)避免重新下載和構(gòu)建依賴(lài)項(xiàng),并在支持的文件系統(tǒng)上利用 Copy-on-Write 和硬鏈接來(lái)最小化磁盤(pán)空間使用。
- 優(yōu)化以便于采用
盡管我們對(duì) Python 打包的未來(lái)有著宏大的愿景,但 uv 的初始版本聚焦于支持我們 uv pip 接口背后的 pip 和 pip-tools,使其可以零配置地被現(xiàn)有項(xiàng)目所采用。
相似地,uv 可以“僅僅”當(dāng)作一個(gè)解析器(uv pip compile 鎖定你的依賴(lài)項(xiàng)),“僅僅”當(dāng)作一個(gè)虛擬環(huán)境創(chuàng)建器(uv venv),“僅僅”當(dāng)作一個(gè)包安裝器(uv pip sync),等等。它既是統(tǒng)一的,又是模塊化的。
- 簡(jiǎn)化的工具鏈
uv 作為一個(gè)單一的靜態(tài)二進(jìn)制文件發(fā)布,能夠替代 pip、pip-tools 和 virtualenv。uv 沒(méi)有直接的 Python 依賴(lài),因此你可以跟 Python 本身分別安裝,避免了在多個(gè) Python 版本(例如,pip vs. pip3 vs. pip3.7)之間選擇 pip 安裝程序。
安裝使用
雖然 uv 將演變成一個(gè)完整的 Python 項(xiàng)目和包管理器(“Cargo for Python”),但像pip-tools 這樣較狹窄的聚焦范圍,讓我們得以解決構(gòu)建此類(lèi)工具所涉及的低級(jí)問(wèn)題(如包安裝),同時(shí)立即提供有用的東西,最小化社區(qū)的使用障礙。
你可以通過(guò)我們的獨(dú)立安裝程序安裝 uv,或者從 PyPI 安裝。
使用 curl:
curl -LsSf https://astral.sh/uv/install.sh | sh
對(duì) Windows:
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
使用 pip 或 pipx:
pip install uv
pipx install uv
uv 能滿足你對(duì)現(xiàn)代 Python 打包工具的所有期望:可編輯安裝、Git 依賴(lài)項(xiàng)、URL 依賴(lài)項(xiàng)、本地依賴(lài)項(xiàng)、約束文件、源碼分發(fā)、自定義索引等,所有這些都設(shè)計(jì)成與你現(xiàn)有的工具無(wú)縫兼容。
uv 支持 Linux、Windows 和 macOS,并已針對(duì)公共的 PyPI 索引進(jìn)行了大規(guī)模測(cè)試。
即插即用的兼容性 API
這個(gè)初始版本主要實(shí)現(xiàn)了 uv 的pip 命令。對(duì)于使用過(guò) pip 和 pip-tools 的人來(lái)說(shuō),這將會(huì)很熟悉:
- 類(lèi)似于pip install,運(yùn)行uv pip install ,可從命令行、requirements 文件或 pyproject.toml 來(lái)安裝 Python 依賴(lài)項(xiàng)
- 類(lèi)似于pip-compile,運(yùn)行uv pip compile 來(lái)生成鎖定的 requirements.txt
- 類(lèi)似于pip-sync,運(yùn)行uv pip sync 來(lái)同步帶有鎖定的 requirements.txt 的虛擬環(huán)境
通過(guò)將這些“低級(jí)”命令放在uv pip下,我們?cè)?CLI 中預(yù)留了空間,用于我們打算在未來(lái)發(fā)布的更“有主見(jiàn)”的項(xiàng)目管理 API,它看起來(lái)將更像 Rye、Cargo 或 Poetry。(想象一下 uv run 、uv build 等等)
uv 也可以通過(guò)uv venv 作為虛擬環(huán)境管理器使用。它比python -m venv 快大約 80 倍,比virtualenv 快 7 倍,且不依賴(lài)于 Python。
圖片
圖注:創(chuàng)建一個(gè)虛擬環(huán)境,有(左)和沒(méi)有(右)pip 及 setuptools 種子包
uv 的虛擬環(huán)境符合標(biāo)準(zhǔn),可以與其他工具互換使用——沒(méi)有鎖定機(jī)制或定制。
新功能
從頭開(kāi)始構(gòu)建我們自己的包管理工具棧,這還為新功能開(kāi)辟了空間。例如:
- uv 支持替換解析策略。 默認(rèn)情況下,uv 遵循標(biāo)準(zhǔn)的 Python 依賴(lài)解析策略,即優(yōu)先選擇每個(gè)包的最新兼容版本。但通過(guò)傳入--resolutinotallow=lowest,庫(kù)作者可以測(cè)試他們的包與依賴(lài)項(xiàng)的最低兼容版本。(這類(lèi)似于 Go 的最小版本選擇。)
- uv 允許針對(duì)任意 Python 目標(biāo)版本進(jìn)行解析。 pip 和 pip-tools 默認(rèn)針對(duì)當(dāng)前安裝的 Python 版本進(jìn)行解析(例如,在 Python 3.12 下運(yùn)行,將生成兼容于 Python 3.12 的解析),uv 支持--python-version 參數(shù),使你能夠在運(yùn)行較新版本的情況下,生成兼容較低版本(例如 Python 3.7)的解析。
- uv 允許依賴(lài)項(xiàng)“覆蓋”。 uv 通過(guò)覆蓋(-o overrides.txt)將 pip 的“約束”概念向前推了一步,允許用戶(hù)通過(guò)覆蓋包的聲明依賴(lài)項(xiàng)來(lái)引導(dǎo)解析器。覆蓋為用戶(hù)提供了一個(gè)逃生艙口,用于解決錯(cuò)誤的上限和其他錯(cuò)誤聲明的依賴(lài)項(xiàng)。
在當(dāng)前形式下,uv 并不適合所有項(xiàng)目。pip 是一個(gè)成熟且穩(wěn)定的工具,支持非常廣泛的場(chǎng)景,并且專(zhuān)注于兼容性。雖然 uv 支持 pip 的大部分功能,但它缺乏對(duì)一些傳統(tǒng)特性的支持,比如 .egg 分發(fā)。
同樣,uv 目前還不支持生成與平臺(tái)無(wú)關(guān)的鎖定文件。這與 pip-tools 相符,但與 Poetry 和 PDM 不同,這使得 uv 更適合圍繞 pip 和 pip-tools 工作流構(gòu)建的項(xiàng)目。
對(duì)于那些深入打包生態(tài)系統(tǒng)的人來(lái)說(shuō),uv 還用 Rust 實(shí)現(xiàn)了符合標(biāo)準(zhǔn)的更多功能,例如 PEP 440(版本標(biāo)識(shí)符)、PEP 508(依賴(lài)項(xiàng)說(shuō)明符)、PEP 517(與構(gòu)建系統(tǒng)無(wú)關(guān)的構(gòu)建前端)、PEP 405(虛擬環(huán)境)等。
"Python 的 Cargo":uv 和 Rye
uv 代表著我們追求 "Python 的 Cargo" 的一個(gè)中間里程碑:一個(gè)統(tǒng)一的 Python 包和項(xiàng)目管理器,它極其快速、可靠且易于使用。
想象一下:一個(gè)單一的二進(jìn)制文件,它可為你安裝 Python,并為你提供使用 Python 所需的一切,不僅包括 pip、pip-tools 和 virtualenv,還有 pipx、tox、poetry、pyenv、ruff 等等。
使用 Python 工具鏈可能是一種低信心體驗(yàn):為新項(xiàng)目或現(xiàn)有項(xiàng)目搭建環(huán)境需要大量的工作,而且命令通常以令人費(fèi)解的方式報(bào)錯(cuò)。相比之下,在 Rust 生態(tài)中做事時(shí),你信任工具會(huì)成功。Astral 工具鏈的目標(biāo)是將 Python 從低信心體驗(yàn)轉(zhuǎn)變?yōu)楦咝判捏w驗(yàn)。
我們對(duì) Python 打包的愿景與 Rye 的愿景相去不遠(yuǎn),Rye 是由 Armin Ronacher 開(kāi)發(fā)的一個(gè)實(shí)驗(yàn)性的項(xiàng)目與包管理工具。
在與 Armin 的交流中,我們清楚地認(rèn)識(shí)到我們的愿景非常接近,但實(shí)現(xiàn)這些愿景需要在基礎(chǔ)工具上作大量投入。例如:構(gòu)建這樣的工具需要一個(gè)非常快速的、端到端集成的、跨平臺(tái)的解析器和安裝器。在 uv 里,我們已經(jīng)構(gòu)建出了這樣的基礎(chǔ)工具。
我們認(rèn)為這是一個(gè)難得的合作機(jī)會(huì),可以避免 Python 生態(tài)破碎。因此,我們與 Armin 合作,很高興地接管了 Rye。 我們的目標(biāo)是將 uv 發(fā)展成一個(gè)生產(chǎn)就緒的 "Python 的 Cargo",并在適當(dāng)?shù)臅r(shí)候提供一個(gè)將 Rye 平滑遷移到 uv 的路徑。
在此之前,我們將維護(hù) Rye,將其遷移成在幕后使用 uv,寬泛地說(shuō),它將成為我們正在構(gòu)建的最終用戶(hù)體驗(yàn)的實(shí)驗(yàn)性測(cè)試床。
雖然合并項(xiàng)目帶來(lái)了一些挑戰(zhàn),但我們致力于在 Astral 的旗幟下構(gòu)建一個(gè)單一的且統(tǒng)一的工具,并在我們發(fā)展 uv 成為一個(gè)合適且全面的繼任者的同時(shí),支持現(xiàn)有的 Rye 用戶(hù)。
最近,我在 Python 潮流周刊 中分享了一個(gè)超級(jí)火爆的項(xiàng)目,這還不到一個(gè)月,它在 Github 上已經(jīng)拿下了 8K star 的亮眼成績(jī),可見(jiàn)其受歡迎程度極高!國(guó)內(nèi)還未見(jiàn)有更多消息,我趁著周末把一篇官方博客翻譯出來(lái)了,分享給大家。
作者:@charliermarsh
譯者:豌豆花下貓@Python貓
英文:uv: Python packaging in Rust (https://astral.sh/blog/uv)
聲明:本翻譯是出于交流學(xué)習(xí)的目的,為便于閱讀,部分內(nèi)容略有改動(dòng)。轉(zhuǎn)載請(qǐng)保留作者信息。