uv 构建后端
构建后端将源代码树(即目录)转换为源代码分发或 wheel 包。
uv 支持所有构建后端(如 PEP 517 所指定的),但也提供了一个原生构建后端 (uv_build
),该后端与 uv 紧密集成,以提高性能和用户体验。
选择构建后端
uv 构建后端是大多数 Python 项目的绝佳选择。它具有合理的默认值,目标是让大多数用户无需配置,但提供灵活的配置以适应大多数 Python 项目结构。它与 uv 紧密集成,以改善消息传递和用户体验。它验证项目元数据和结构,防止常见错误。而且,它非常快。
uv 构建后端目前仅支持纯 Python 代码。构建带有扩展模块的库需要替代后端。
提示
虽然后端支持许多用于配置项目结构的选项,但当需要构建脚本或更灵活的项目布局时,请考虑使用 hatchling 构建后端。
使用 uv 构建后端
要在现有项目中使用 uv 作为构建后端,请将 uv_build
添加到 pyproject.toml
中的 [build-system]
部分
注意
uv 构建后端遵循与 uv 相同的 版本控制策略。包括 uv_build
版本的上限可确保您的软件包在新版本发布时继续正确构建。
要创建一个使用 uv 构建后端的新项目,请使用 uv init
构建项目时,例如使用 uv build
,将使用 uv 构建后端来创建源代码分发和 wheel 包。
捆绑构建后端
构建后端作为单独的包 (uv_build
) 发布,该包针对可移植性和小二进制大小进行了优化。但是,uv
可执行文件还包括构建后端的副本,如果其版本与 uv_build
要求兼容,则该副本将在 uv 执行的构建期间使用,例如,在 uv build
期间。如果不兼容,将使用 uv_build
包的兼容版本。其他构建前端,例如 python -m build
,将始终使用 uv_build
包,通常选择最新的兼容版本。
模块
Python 包应包含一个或多个 Python 模块,这些模块是包含 __init__.py
的目录。默认情况下,预期在 src/<package_name>/__init__.py
处有一个根模块。
例如,名为 foo
的项目的结构将是
uv 会规范化包名称以确定默认模块名称:包名称转换为小写,点和破折号替换为下划线,例如,Foo-Bar
将转换为 foo_bar
。
src/
目录是模块发现的默认目录。
可以使用 module-name
和 module-root
设置更改这些默认值。例如,要在根目录中使用 FOO
模块,如项目结构中所示
正确的构建配置将是
命名空间包
命名空间包旨在用于多个包将模块写入共享命名空间的情况。
命名空间包模块由 module-name
中的 .
标识。例如,要在共享命名空间 foo
中打包模块 bar
,项目结构将是
并且 module-name
配置将是
重要
__init__.py
文件不包含在 foo
中,因为它是一个共享命名空间模块。
也可以有具有多个根模块的复杂命名空间包,例如,项目结构如下
虽然我们不推荐这种结构(即,您应该使用具有多个包的工作区),但通过将 module-name
设置为名称列表来支持它
对于具有多个模块或复杂命名空间的包,可以使用 namespace = true
选项来避免显式声明每个模块名称,例如
警告
使用 namespace = true
会禁用安全检查。强烈建议在传统项目之外使用显式模块名称列表。
namespace
选项也可以与 module-name
一起使用以显式声明根,例如,对于项目结构
建议的配置是
存根包
构建后端还支持构建类型存根包,这些包通过包或模块名称上的 -stubs
后缀来标识,例如 foo-stubs
。类型存根包的模块名称必须以 -stubs
结尾,因此 uv 不会将 -
规范化为下划线。此外,uv 将搜索 __init__.pyi
文件。例如,项目结构将是
类型存根模块也支持命名空间包。
文件包含和排除
构建后端负责确定应将源树中的哪些文件打包到分发包中。
要确定要包含在源代码分发包中的文件,uv 首先添加包含的文件和目录,然后删除排除的文件和目录。这意味着排除始终优先于包含。
默认情况下,uv 会排除 __pycache__
、*.pyc
和 *.pyo
。
构建源代码分发包时,包含以下文件和目录
pyproject.toml
tool.uv.build-backend.module-root
下的模块。project.license-files
和project.readme
引用的文件。tool.uv.build-backend.data
下的所有目录。- 所有匹配来自
tool.uv.build-backend.source-include
的模式的文件。
从这些文件中,将删除匹配 tool.uv.build-backend.source-exclude
和 默认排除项的项目。
构建 wheel 包时,包含以下文件和目录
tool.uv.build-backend.module-root
下的模块project.license-files
引用的文件,这些文件被复制到.dist-info
目录中。project.readme
,它被复制到项目元数据中。tool.uv.build-backend.data
下的所有目录,这些目录被复制到.data
目录中。
从这些文件中,删除 tool.uv.build-backend.source-exclude
、tool.uv.build-backend.wheel-exclude
和默认排除项。应用源代码分发排除项是为了避免从源代码树到 wheel 包的源构建包含比从源代码树到源代码分发包到 wheel 包的构建更多的文件。
没有特定的 wheel 包含项。必须只有一个顶级模块,并且所有数据文件必须位于模块根目录下或在相应的数据目录中。大多数包将少量数据存储在模块根目录中,与源代码一起。
包含和排除语法
包含是锚定的,这意味着 pyproject.toml
仅包含 <root>/pyproject.toml
,而不包含 <root>/bar/pyproject.toml
。要递归包含目录下的所有文件,请使用 /**
后缀,例如 src/**
。递归包含也是锚定的,例如,assets/**/sample.csv
包含 <root>/assets
或其任何子级中的所有 sample.csv
文件。
注意
为了性能和可重现性,请避免使用没有锚点的模式,例如 **/sample.csv
。
排除项未锚定,这意味着 __pycache__
排除所有名为 __pycache__
的目录,而与其父目录无关。排除项的所有子项也被排除。要锚定目录,请使用 /
前缀,例如,/dist
将仅排除 <root>/dist
。
所有接受模式的字段都使用来自 PEP 639 的缩减的便携式 glob 语法,并添加了可以使用反斜杠转义字符。