Uv 很棒,但其包管理用户体验很糟糕
摘要
本文批评了 uv 包管理 CLI 的用户体验,指出了缺少如 `uv outdated` 等特性、没有上限的默认版本约束不安全,以及与 pnpm 和 Poetry 相比笨重的升级命令等问题。
暂无内容
查看缓存全文
缓存时间:
2026/05/22 00:37
# uv 棒极了,但它的包管理用户体验一团糟
来源:https://www.loopwerk.io/articles/2026/uv-ux-mess/
英雄图片Astral 的 uv (https://docs.astral.sh/uv/)席卷了 Python 世界,而且理由充分。它快如闪电,轻松处理 Python 版本,并将半打工具替换为单个二进制文件。我之前写过关于它的多篇文章 (https://www.loopwerk.io/articles/tag/uv/)。
使用 uv 启动一个新 Python 项目并添加你的第一批依赖项非常简单。但一旦你越过初始设置进入项目的维护阶段——即检查过时的包并进行例行升级——CLI 就开始显得出奇地笨拙,与 pnpm 或 Poetry 等同类工具相比。
## 查找过时的包
在我的 JavaScript 项目中,如果我想查看哪些需要更新,我会运行:
``
$ pnpm outdated
``
这会清晰简洁地列出过时的包、它们的当前版本、最新版本以及你的约束条件允许的版本。
在 uv 中,没有 `uv outdated`。相反,你必须记住以下冗长的命令:
``
$ uv tree --outdated --depth 1
``
输出也有问题。它不仅仅显示哪些过时了,它显示你整个顶层依赖树,并在有更新可用的旁边添加一个小注释。如果你有 50 个依赖项而只有两个过时,你仍然需要扫描一个 50 行的列表。
Poetry 的 `poetry show --outdated` 命令也好不了多少,但至少它只显示实际过时的包。
## 默认不安全的版本约束
这是 uv 与 pnpm 和 Poetry 在哲学上的最大分歧,而且对生产稳定性来说非常危险。
### pnpm/Poetry 的处理方式
当你使用 `pnpm add` 添加一个包时,它会将其写入 `package.json`,使用带插入符号的要求 (`^1.23.4`)。开头的插入符号意味着允许任何 1.x.x 版本,但不会更新到 2.0.0。
Poetry 默认也做同样的事情,使用类似 `>=1.23.4,<2.0.0` 的格式。我觉得这不如 `^1.23.4` 易读,但效果是一样的。
在这两种情况下,**更新默认是安全的**。你可以每天早上运行 `pnpm update` 或 `poetry update`,并且对构建不会因主要 API 变更而中断充满信心(假设你依赖的包遵循 SemVer)。
### uv 的处理方式
当你运行 `uv add pydantic` 时,它会将以下内容插入到你的 `pyproject.toml` 中:
``
dependencies = [
"pydantic>=2.13.4",
]
``
注意缺少上界。在 uv 看来,pydantic 版本 2、3 和 100 都是完全可以接受的。
这意味着 uv 更新**默认是不安全的**。如果你运行批量更新,你获得的不仅仅是 bug 修复;你等于接受了依赖图中每个维护者发布的每一个破坏性变更。
## 升级命令的糟糕用户体验
在 uv 中实际执行更新的命令感觉像是为机器设计的,而不是为人。
如果你想在 pnpm 或 Poetry 中更新所有内容,只需简单的 `pnpm update` 或 `poetry update` 命令。在 uv 中,你要使用:
``
$ uv lock --upgrade
``
由于上面提到的“没有上界”问题,`uv lock --upgrade` 是一个核选项。它会将你的锁文件中的每个包升级到绝对最新版本,忽略 SemVer 安全。这包括你从未听说过的深层嵌套依赖项!祝你好运,最好希望没有任何地方存在破坏性变更。
一旦你意识到这太冒险,你就会只想升级特定的包。在浏览 `uv tree --outdated --depth 1` 的糟糕输出来找到它们之后,语法就变成了重复的苦差事。
pnpm 的做法:
``
$ pnpm update pydantic httpx uvicorn
``
uv 的做法:
``
$ uv lock --upgrade-package pydantic --upgrade-package httpx --upgrade-package uvicorn
``
当你想更新一堆包时,必须为每个项目重复 `--upgrade-package` 标志是一个巨大的麻烦。我不明白为什么 uv 命令的用户体验这么差。
## 希望尚存:bounds 标志
幸运的是,uv 最近为 `uv add` 引入了一个 `--bounds` 选项:
``
$ uv add pydantic --bounds major
``
这会生成我们期望的更安全的 `pydantic>=2.13.4,<3.0.0` 约束。然而,目前这还是一个选择性加入的功能。你必须记得每次都输入它,而且目前它被视为预览功能。
在 `--bounds major`(或类似配置)成为默认行为之前,uv 用户基本上被迫在两种糟糕选项之间选择:
1. 手动编辑 `pyproject.toml` 为每个依赖项添加上界。
2. 担心 `uv lock --upgrade` 会意外引入一个破坏性主版本变更。
## 我希望看到的
我喜欢 uv。它的速度是革命性的,它管理 Python 工具链的方式无与伦比。但作为一个包管理器,在项目维护方面的开发者体验目前不如之前的工具。
我们需要一个专门的 `uv outdated` 命令来过滤噪音,一个更符合人体工程学的 `update` 命令(不需要重复标志),以及默认尊重语义化版本约束的版本约束。
在那之前,我将以高度怀疑的态度仔细检查我的锁文件变更的每一行。
相似文章
Hacker News Top
Octomind 是一个开源的、基于 Rust 的 AI 编码智能体运行时,以 CLI 为优先交互方式,通过 MCP 工具让大语言模型访问代码仓库,支持交互式、管道、守护进程、WebSocket 和 ACP 子智能体模式,并提供基于 TOML 的安全护栏、预算控制和自适应压缩。
Lobsters Hottest
git-loom 1.0 将多个功能分支编织成一个集成分支,让开发者无需切换分支即可跨分支提交、修改提交、拆分提交和调整提交顺序,其灵感源自 jujutsu 和 GitButler。
X AI KOLs Timeline
Matt Pocock 试验一种组合架构:本地长期运行的 orchestrator 线程与软件工厂(沙盒化实现者、探索任务等)相连,通过 CLI 管理线程、复盘和 cron 任务,让人类用自然语言交互。
X AI KOLs Timeline
介绍 Labelme——一款基于 Python/Qt 的开源图像标注工具,支持绘制多边形、矩形框、圆形和点,并可通过 SAM、EfficientSAM、YOLO-World 和 SAM3 实现 AI 辅助标注,支持 VOC/CCO 格式导出以及视频标注。
X AI KOLs Timeline
整理了 6 个打通学习→策略→回测→实盘链路的 GitHub 量化交易项目:awesome-quant、machine-learning-for-trading、quant-trading、backtrader、zipline 和 ccxt。