目录
简单打包
Python 包现在可以使用现代构建系统,而不是传统但冗长的 setuptools 和 setup.py
。您选择的构建系统并不重要;它们都使用在 PEP 621 中引入的 标准配置语言。PyPA 的 Flit 是一个不错的选择。 scikit-build-core 和 meson-python 正在开发中,以支持这种配置,使二进制扩展包也能从中受益。这些 PEP 621 工具目前包括 Hatch、PDM、Flit 和 Setuptools。 Poetry 最终将在 2.0 版本中获得支持。
传统文件
这些系统不使用也不需要
setup.py
、setup.cfg
或MANIFEST.in
。这些文件是用于 setuptools 的。当然,除非您正在使用 setuptools,setuptools 仍然使用MANIFEST.in
。您可以使用pipx run hatch new --init
或 ini2toml 转换旧文件。
选择后端
后端以相同的方式处理元数据,因此选择取决于您如何指定哪些文件进入 SDist 以及其他功能,例如从 VCS 获取版本。如果您没有现有的偏好,hatchling 是一个绝佳的选择,它平衡了速度、可配置性和可扩展性。
pyproject.toml: build-system
PY001 包必须具有 pyproject.toml
文件 PP001,用于选择后端
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
pyproject.toml: project table
元数据以 基于标准 的格式指定
[project]
name = "package"
description = "A great package."
readme = "README.md"
authors = [
{ name = "My Name", email = "me@email.com" },
]
maintainers = [
{ name = "My Organization", email = "myemail@email.com" },
]
requires-python = ">=3.9"
dependencies = [
"typing_extensions",
]
classifiers = [
"Development Status :: 4 - Beta",
"License :: OSI Approved :: BSD License",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Topic :: Scientific/Engineering :: Physics",
]
[project.urls]
Homepage = "https://github.com/organization/package"
Documentation = "https://package.readthedocs.io/"
"Bug Tracker" = "https://github.com/organization/package/issues"
Discussions = "https://github.com/organization/package/discussions"
Changelog = "https://package.readthedocs.io/en/latest/changelog.html"
您可以在 packaging.python.org、Flit 或 Whey 中详细了解每个字段以及所有允许的字段。请注意,“主页”很特殊,它替换了旧的 url 设置。
附加功能
建议使用附加功能来代替或补充创建需求文件。这些附加功能 a) 与安装需求和其他内置工具正确交互,b) 通过 PyPI 安装时直接可用,c) 允许在 requirements.txt
、install_requires
、pyproject.toml
以及大多数其他传递需求的地方。
这是一个简单附加功能的示例
[project.optional-dependencies]
test = [
"pytest >=6.0",
]
mpl = [
"matplotlib >=2.0",
]
可以使用包名称来使用自身依赖,例如 dev = ["package[test,examples]"]
,但这需要 Pip 21.2 或更高版本。我们建议至少提供 test
和 docs
。
命令行
如果您想发布一个用户可以从命令行运行的“应用程序”,您需要添加一个 script
入口点。格式为
[project.scripts]
cliapp = "package.__main__:main"
格式为命令行应用程序名称作为键,值为函数路径,后面跟着冒号,然后是将要调用的函数。如果您使用 __main__.py
作为文件,那么后面跟着模块的 python -m
也将起作用来调用应用程序(在这种情况下,__name__
将为 "__main__"
)。
对于 requires-python
,您应该指定所需的最低版本,并且不应该对其设置上限 PY004,因为此字段用于反向求解通过此检查的旧包版本,允许您安全地放弃 Python 版本。
包结构
所有包应该都有一个 src
文件夹,包代码驻留在其中,例如 src/<package>/
。这可能看起来很麻烦;毕竟,如果您没有 src
文件夹,您可以在主目录中键入“python
”并避免安装它!但是,这是一种不好的做法,会导致一些常见的错误,例如运行 pytest
并获取本地版本而不是已安装版本 - 如果您构建库的部分内容或访问包元数据,这显然会出错。
不幸的是,这并不属于 [project]
中的标准元数据,因此取决于您使用的后端。Hatchling、Flit、PDM 和 setuptools 使用自动检测。
如果您不匹配包名称和导入名称(除了非常特殊的情况外,您应该这样做),您可能需要在此处进行额外的配置。
您应该有一个 README
PY002 和一个 LICENSE
PY003 文件。您应该有一个 docs/
文件夹 PY004。您应该有一个 /tests
文件夹 PY005(推荐)和/或一个 src/<package>/tests
文件夹。
版本控制
您可以手动指定版本(如示例所示),但后端通常提供一些自动功能来帮助您避免这种情况。如果您要求 Flit,它会从文件中提取此信息。Hatchling 和 PDM 可以被指示在文件中查找或使用 git。
您始终需要指定版本将使用以下方式动态提供
dynamic = ["version"]
然后您将配置您的后端以计算版本。
Hatchling 动态版本控制
您可以告诉 hatchling 从 VCS 获取版本。将 hatch-vcs
添加到您的 build-backend.requires
中,然后添加以下配置
[tool.hatch]
version.source = "vcs"
build.hooks.vcs.version-file = "src/<package>/version.py"
或者您可以告诉它在文件中查找它(有关任意正则表达式的详细信息,请参阅文档)
[tool.hatch]
version.path = "src/<package>/__init__.py"
(将 <package>
替换为包路径)。
您还应该添加这两个文件
.git_archival.txt
:
node: $Format:%H$
node-date: $Format:%cI$
describe-name: $Format:%(describe:tags=true,match=*[0-9]*)$
以及 .gitattributes
(或者如果您已经在使用此文件,请添加此行)
.git_archival.txt export-subst
这将允许 git 存档(包括从 GitHub 生成的存档)也支持版本控制。
在 SDist 中包含/排除文件
这是特定于工具的。
- Hatchling 信息在此处。Hatchling 默认情况下使用您的 VCS 忽略文件,因此请确保它是准确的(无论如何这都是一个好主意)。
- Flit 信息在此处。Flit 在很多情况下需要手动包含/排除,例如使用脏工作目录。
- PDM 信息在此处.
- Setuptools 仍然使用
MANIFEST.in
。
如果您使用标准工具,即使 Flit 可以使用其自己的工具执行此操作,它也不会使用 VCS(如 git)来填充 SDist。因此,请确保列出明确的包含/排除规则,并测试内容
# Show SDist contents tar -tvf dist/*.tar.gz # Show wheel contents unzip -l dist/*.whl
Flit需要在您的
[project]
部分中设置license.file
以确保它找到许可证文件。