@charliermarsh:一年前我在Jane Street做的这个演讲,是迄今为止人们在面对面交流中提及最多的。似乎大家都很喜欢!

X AI KOLs Following 工具

摘要

Charlie Marsh的演讲解释了uv——Astral开发的基于Rust的Python包管理器——如何通过CDCL SAT求解器和统一锁定文件来解决依赖解析问题,并通过从头重新设计工具链实现了极快的速度。

一年前我在Jane Street做的这个演讲,是迄今为止人们在面对面交流中提及最多的。似乎大家都很喜欢! https://t.co/GPFnL34m08
查看原文
查看缓存全文

缓存时间: 2026/06/26 10:10

一年前我在Jane Street做的这场演讲,至今仍是线下最常被人提及的一场。大家似乎很喜欢它!

https://t.co/GPFnL34m08


TL;DR:Charlie Marsh 解释了 uv(一个基于 Rust 的 Python 包管理器)如何通过 CDCL SAT 求解器和统一的可移植锁文件解决依赖解析问题,并通过从零重新设计整个工具链实现极致的速度。

引言:为什么还要再构建一个 Python 包管理器?

Charlie Marsh(Astral 创始人,以 Ruff 代码检查器和格式化器闻名)在 Jane Street 介绍了 uv —— 一个快速、一体化的 Python 包和项目管理器。uv 于 2 月发布,月下载量已达 1600 万,占 PyPI 请求量的 10% 以上。本演讲涵盖:

  • uv 是什么以及为何要构建它
  • 创建最先进解析器所面临的技术挑战
  • 能够改变用户使用 Python 方式的性能案例分析

核心动机:Python 的打包生态系统碎片化(pip、pipx、pyenv、virtualenv、poetry 等)。uv 的目标是成为 单个静态二进制文件,完成所有任务——安装 Python、创建虚拟环境、解析依赖、安装包、构建分发——模仿 Rust 统一的 Cargo 体验。

完全统一的技术栈的力量

与以往 Python 包管理器的尝试不同,uv 并非构建在任何现有工具之上。它从零开始实现所有功能:

  • 不依赖 pip 或 setuptools
  • 不继承旧版 Python 打包的任何限制
  • 单一的锁文件格式(如 uv.lock),记录每一个细节:包名、版本、来源、依赖、SHA 和文件大小

这种统一使 uv 能够将虚拟环境视为廉价、一次性的资源。“销毁并重建一个虚拟环境极其快速——我们努力让它变得如此廉价,以至于你根本不在乎它的纯净状态。”

uv 如何安装包:生命周期

当你运行 uv pip installuv sync 时,有两个主要接口可用:

  1. pip 兼容的命令行uv pip install 可直接替换(例如,用 uv pip install pydantic 替代 pip install pydantic
  2. 更高级别的命令uv sync / uv lock 用于基于项目的流程,你声明依赖,让 uv 管理一切

生命周期:

  1. 查找 Python 解释器 – uv 不附带 Python,因此它会定位一个现有的解释器(此处略去具体细节)。
  2. 发现需求 – 从命令行或 requirements.txt 中读取。
  3. 解析依赖 – 将需求解析为一组兼容的版本。这是包管理器的核心。
  4. 生成锁文件 – 一个完整的图,包含确切的版本、来源和校验和。
  5. 创建安装计划 – 将当前环境状态与所需的锁文件状态进行比较,然后更新(卸载旧版本,安装新版本)。

难题 #1:Python 不支持多版本共存

在 Python 中,你 无法同时安装同一包的两个版本(与 Rust 或 Node 不同)。导入系统使用以模块名作为键的全局缓存,因此你不能同时拥有 pydantic==1.*pydantic==2.*

示例: 假设你的项目依赖于 vcr(需要 pydantic>=2)和一个旧的 langchain(需要 pydantic<2)。在 Python 中,这个依赖图是无解的。uv 会给出清晰的错误消息:“由于你的项目依赖于 langchain,它要求 pydantic<2,而 vcr 要求 pydantic>=2,这两者无法同时满足。”

如果用户说“我接受 vcr 的任何版本”,uv 必须 回溯 —— 测试 vcr 的每一个版本,以找到一个满足所有约束的版本。这本质上是一个布尔可满足性问题(SAT),是 NP 难的。

uv 的方法: 它使用 CDCL(冲突驱动子句学习)SAT 求解器。这是一种智能技术,用于探索依赖空间,从冲突中学习,并剪枝搜索树。“最坏情况下是指数级的,但在实践中,对于 Python 的包宇宙来说,它足够快。”

难题 #2:平台与版本相关的条件

Python 的依赖说明符极其丰富:importlib-metadata; python_version < "3.10"colorama; sys_platform == "win32" 等。这产生了大量的条件性需求。

简单的方法: 为特定目标求解(例如,Windows + Python 3.12)—— 只需过滤掉无关的约束。但 uv 想要生成一个 通用锁文件,可以在任何机器上工作。这意味着解析器必须解决一个巨大的问题:对于每个包版本,考虑所有可能的平台、Python 版本和特性标志组合,并确保锁文件在所有地方都有效。

“这正是使解析器成为 uv 最困难部分的原因。”

改变工作流程的性能

速度不仅仅是基准分数;它改变了人们使用 Python 的方式:

  • Ruff 先例: 过去只在 CI 中运行的任务,现在作为预提交钩子运行,因为它们太快了。
  • uv 先例: 创建虚拟环境并从零安装所有依赖只需几秒,而非几分钟。开发者现在可以将环境视为短暂的——销毁并重建,无需担心。
  • 目前所有 PyPI 流量的 10% 来自 uv,尽管它发布仅约 6 个月。

演讲以案例分析结束(未完全转录),展示了具体的优化:通过并行 HTTP 加速下载、流式传输和缓存元数据、基于锁文件的增量安装,以及无需垃圾回收器的 Rust 内存安全性。

结论:Python 工具的新时代

uv 代表了一次深思熟虑的尝试,通过提供统一、极速的即插即用替代品来改变 Python 打包格局。它的采用表明社区渴望简单和速度。正如 Charlie 所说:“当工具速度快十倍时,你与它的关系会彻底改变。”

来源:@charliermarsh – “This talk that I gave at Jane Street a year ago…” (https://www.youtube.com/watch?v=gSKTfG1GXYQ)

相似文章