uv Preview 特性机制详解:启用方式、优先级顺序与全部 Preview Feature 列表
【免费下载链接】uvAn extremely fast Python package and project manager, written in Rust.项目地址: https://gitcode.com/GitHub_Trending/uv/uv
本文以官方文档 docs/concepts/preview.md 为主体,完整讲解 uv 的 preview(预览)特性机制:如何通过命令行、环境变量和配置文件启用或禁用预览功能,当前版本支持的全部 preview feature 名称与用途,以及从源码层面(crates/uv-preview/src/lib.rs、crates/uv/src/settings.rs)理解特性的解析优先级、未知特性的容错行为和"配置加载前生效"等特殊限制,帮助你在安全尝鲜新特性的同时准确理解其生效边界。
什么是 Preview 特性
uv 包含一组需要显式开启的 opt-in preview 特性。其设计目标是:在某个行为变更正式对所有用户默认开启之前,先向社区提供反馈机会,并在充分验证"该变更总体是净收益"之后再全量放开。因此 preview 特性通常处于"行为可能随时变化"的状态,官方文档在 CLI 帮助中也明确提示 "Preview features may change without warning"。
从源码结构看,每个 preview 特性都是 crates/uv-preview/src/lib.rs 中PreviewFeature位标记枚举(#[bitflags],repr(u64))的一个变体,例如Pylock、JsonOutput、FormatCommand等;运行时所有已启用特性被打包进一个Preview结构体(内部是BitFlags<PreviewFeature>),并通过is_enabled(flag)进行判断。
启用 Preview 特性的四种方式
1.--preview标志:一次性开启全部
要开启所有preview 特性,使用--preview全局标志:
$ uv run --preview ...2.UV_PREVIEW环境变量
或者设置UV_PREVIEW环境变量(等价于布尔开关):
$ UV_PREVIEW=1 uv run ...在 CLI 定义中(见 crates/uv-cli/src/lib.rs),--preview使用BoolishValueParser,即接受1、true等布尔值写法,且通过overrides_with("no_preview")与--no-preview互斥覆盖。
3.--preview-features标志:按名称精确启用
要只启用特定的 preview 特性,使用--preview-features标志:
$ uv run --preview-features foo ...该标志可以重复出现以启用多个特性:
$ uv run --preview-features foo --preview-features bar ...也可以写成逗号分隔列表:
$ uv run --preview-features foo,bar ...逗号分隔在 crates/uv-cli/src/lib.rs 中通过value_delimiter = ','实现;该标志还有别名--preview-feature,并且每个名称在解析时会先trim掉首尾空白(单元测试 crates/uv-preview/src/lib.rs 验证了"pylock , add-bounds"这样的写法也能正确解析)。
4.UV_PREVIEW_FEATURES环境变量与配置文件
UV_PREVIEW_FEATURES环境变量用法相同,例如:
$ UV_PREVIEW_FEATURES=foo,bar uv run ...preview 特性也可以在uv.toml、pyproject.toml的[tool.uv]表或 PEP 723 元数据(# /// script块)中启用:
preview-features = ["foo", "bar"]设置preview-features = true则等价于开启全部preview 特性。配置项的定义见 crates/uv-settings/src/settings.rs,其中preview-features既可接受布尔值(true表示全部开启),也可接受特性名称列表。
两个重要限制
- 配置加载前生效的特性无法从配置文件启用:少数 preview 特性在读取任何配置文件之前就已经影响行为(例如
target-workspace-discovery决定项目发现从哪个目录起步、project-directory-must-exist决定是否在发现阶段拒绝非法--project路径),它们只能由--preview/--preview-features标志或环境变量开启,写在uv.toml里不会生效。 - 同时写
preview与preview-features会报错:PreviewOption::try_from在两者同时为Some时返回错误 "cannot specify bothpreviewandpreview-features"(见 crates/uv-settings/src/settings.rs)。旧版布尔配置键preview已标记为 deprecated,建议统一使用preview-features。
解析优先级:多种来源冲突时谁说了算
文档只列举了各种启用方式,但没说清它们之间的优先级。crates/uv/src/settings.rs 中的resolve_preview函数给出了明确的裁决顺序:
- 显式的
--preview/--no-preview标志优先级最高,直接返回Preview::all()或Preview::default(); UV_PREVIEW=true环境变量(布尔为真)开启全部;- 配置文件中的布尔全开(
preview = true或preview-features = true); - 命令行显式指定的特性名称(
--preview-features非空时)优先于配置文件中声明的名称列表; - 其余情况回退到工作区配置(
uv.toml/pyproject.toml/ PEP 723 元数据)中的preview-features列表。
值得注意的一点是,命令行的具名特性与配置文件的具名特性之间是"覆盖"而非"合并"关系:只要命令行提供了--preview-features,配置文件中的名称列表即被整体忽略。
此外,crates/uv/src/lib.rs 显示 uv 会在配置发现之前先执行一次"早期预览解析"(此时 workspace 配置还不可用,只取 CLI 标志与环境变量),把结果写入全局uv_preview::set(...),这正是"配置加载前生效的特性"能够起作用的机制;在后续完整配置解析完成后,uv_preview::set再次更新并调用uv_preview::finalize()将状态锁定(crates/uv/src/lib.rs)。uv-preview内部用OnceLock+ 状态机(Provisional→Final)保证finalize之后不可再修改,防止运行时出现不一致的预览状态(见 crates/uv-preview/src/lib.rs)。
无需显式启用也能"顺带"使用的特性
官方文档特别指出:如果一个 preview 特性的行为变化是由某种用户交互自然"门控"的,那么你可以在不改任何 preview 设置的情况下直接使用该行为。典型例子是pylock.toml支持:在pylock特性仍处于 preview 期间,你直接用uv pip install指向一个pylock.toml文件即可安装,因为"显式指定了pylock.toml文件"本身就表明你希望使用这个特性——但 uv 会打印一条"该特性处于 preview"的警告,显式开启 preview 特性可以消除该警告。
类似的门控逻辑也出现在源码中,例如--index按名称引用已配置索引时,若未开启index-by-name特性会提示 "Referencing an index by name is experimental and may change without warning. Pass--preview-features ...to disable this warning"(见 crates/uv-cli/src/lib.rs)。
未知特性名称:警告但不报错
文档明确:出于向后兼容,启用一个不存在的 preview 特性只会产生警告而不会报错,无论该名称来自哪个来源。对应实现是MaybePreviewFeature枚举(crates/uv-preview/src/lib.rs):解析成功则为Known(PreviewFeature),失败则保留原始字符串为Unknown(String);随后Preview::from_feature_names(crates/uv-preview/src/lib.rs)对每个未知名称调用warn_user_once!输出Unknown preview feature: \{name}`并跳过。这样做的意义在于:当用户配置了下一个版本才引入的特性名称时,旧版本不会直接崩掉整个命令。配套的单测 [crates/uv-preview/src/lib.rs](https://link.gitcode.com/i/2cd6129f4aa19c1c72b761043d381bc5#L562-L565) 验证了"unknown-feature,pylock"只启用pylock一个特性。另外,完全空白的特性名称(如--preview-features ""或列表中的空项)会报preview feature name cannot be empty` 错误。
部分特性还定义了别名:PreviewFeature上的#[preview(alias = ...)]属性让旧名称继续可用,例如format→format-command、audit→audit-command、check→check-command(见 crates/uv-preview/src/lib.rs)。
当前可用的 Preview 特性列表
文档中"Available preview features"一节的内容是由代码生成的:cargo dev generate-preview-features-reference会读取PreviewFeature枚举的元数据(PreviewMetadata宏)并按名称排序渲染成 Markdown(生成器见 crates/uv-dev/src/generate_preview_features_reference.rs,生成产物为构建期文件docs/reference/.preview-features.md)。以生成器内置的完整快照为准确,当前仓库包含以下特性(kebab-case 名称 + 用途):
| 特性名称 | 说明 |
|---|---|
add-bounds | 允许配置uv add调用的默认版本边界 |
adjust-ulimit | 在 Unix 上于启动时把进程软打开文件数上限提升到硬上限 |
artifact-hash-filtering | 将生成的依赖哈希限制在二进制与构建策略允许的构件范围内 |
audit-command | 允许使用uv audit和uv tool audit(别名audit) |
auth-helper | 允许将uv auth helper作为外部工具的凭据助手使用 |
azure-endpoint | 允许使用 Azure 凭据对配置的 Azure Blob Storage 端点签名请求 |
cache-physical-space | 报告缓存清理实际回收的物理磁盘空间(计入硬链接与写时复制克隆) |
cache-size | 允许使用uv cache size |
centralized-project-envs | 将项目虚拟环境集中存储在 uv 缓存中 |
check-command | 允许使用uv check(别名check) |
content-addressed-cache | 在缓存中启用内容寻址的 wheel 归档 |
detect-module-conflicts | 当多个包会把冲突的 Python 模块装入同一环境时发出警告 |
extra-build-dependencies | 允许为包构建指定额外依赖 |
format-command | 允许使用uv format(别名format) |
gcs-endpoint | 允许对配置的 Google Cloud Storage 端点签名请求 |
index-by-name | 允许用--index和--default-index按名称选择已配置的索引 |
index-exclude-newer | 允许为已配置的包索引设置exclude-newer |
index-hash-algorithm | 允许为已配置的包索引强制要求某种哈希算法 |
init-project-flag | 拒绝uv init中已废弃的--project选项 |
json-output | 为多个 uv 命令启用--output-format json |
lock-without-metadata | 在uv.lock中省略package.metadata表 |
lockfile-format-check | 使用--locked或--check时拒绝非规范化的 lockfile 格式 |
malware-check | 允许uv sync等命令在安装前通过 OSV 检查恶意软件 |
metadata-json | 在构建的 wheel 中包含 JSON 元数据文件 |
native-auth | 启用将凭据存储到系统原生位置(如 keyring) |
no-distutils-patch | 对 Python 3.10+ 不再向虚拟环境安装_virtualenv.py/_virtualenv.pth的 distutils 补丁 |
package-conflicts | 允许在包级别定义 workspace conflicts |
packaged-init | 让uv init默认创建带src/布局、构建系统和脚本入口的打包应用 |
project-directory-must-exist | 拒绝非法的--project路径(除uv init外必须已存在)。在配置加载前生效 |
publish-require-normalized | 发布时要求规范化的发行文件名,跳过未规范化的文件 |
pylock | 允许从pylock.toml文件安装 |
python-install-default | 允许安装python/python3可执行文件到系统 |
relocatable-envs-default | 默认创建可重定位(relocatable)的虚拟环境 |
s3-endpoint | 允许对配置的 S3 兼容端点签名请求 |
sbom-export | 允许使用uv export --format=cyclonedx1.5 |
special-conda-env-names | 不再把名为base或root的 Conda 环境视为特殊 |
tar-codec | 使用新的tar-codec编解码后端替代astral-tokio-tar |
target-workspace-discovery | uv run的本地目标所在目录(而非 CWD)作为项目发现起点。在配置加载前生效 |
toml-backwards-compatibility | 构建 sdist 时将pyproject.toml重写为 TOML 1.0,并将原文件保留为pyproject.toml.orig |
tool-install-locks | 为每个已安装工具保存uv.lock,用于可复现的安装、升级与审计 |
venv-safe-clear | 除非提供--force,否则uv venv --clear不会清空不含pyvenv.cfg的目录 |
workspace-dir | 允许使用uv workspace dir |
workspace-list | 允许使用uv workspace list |
workspace-list-scripts | 允许使用uv workspace list --scripts |
workspace-metadata | 允许使用uv workspace metadata |
使用示例(开启最常用的几个):
$ uv run --preview-features json-output,pylock ...禁用 Preview 特性
--no-preview选项可以禁用 preview 特性。从 crates/uv/src/settings.rs 可见它返回Preview::default()(即关闭全部特性),并且由于--preview与--no-preview相互overrides_with,二者中最后出现的那个决定最终状态——这意味着可以用--preview-features pylock --no-preview之类的组合在单条命令中整体关掉预览行为(例如在 CI 中临时回归稳定行为)。
小结与使用建议
- 尝鲜单个特性时用
--preview-features <name>(或UV_PREVIEW_FEATURES)精确开启,避免无差别打开全部实验性行为; - 在
uv.toml/pyproject.toml的preview-features中固化项目级配置,但注意"配置加载前生效"的特性(target-workspace-discovery、project-directory-must-exist)必须走 CLI 或环境变量; - 遇到 "This option is in preview and may change in any future release" 提示时,说明该命令/选项仍属实验阶段,行为与接口都可能调整;
- 特性列表随版本演进,最新清单以生成器(
cargo dev generate-preview-features-reference)产物和 crates/uv-preview/src/lib.rs 中PreviewFeature枚举为准,本文表格对应当前仓库快照。
【免费下载链接】uvAn extremely fast Python package and project manager, written in Rust.项目地址: https://gitcode.com/GitHub_Trending/uv/uv
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考