news 2026/9/10 20:27:47

Poetry 多 README 文件支持实战:readme 列表配置、源码实现与构建产物验证

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Poetry 多 README 文件支持实战:readme 列表配置、源码实现与构建产物验证

Poetry 多 README 文件支持实战:readme 列表配置、源码实现与构建产物验证

【免费下载链接】poetryPython packaging and dependency management made easy项目地址: https://gitcode.com/GitHub_Trending/po/poetry

在 Poetry 项目中,一个包往往只对应一个 README 文件,但当你需要同时维护「用户使用说明」与「变更日志」、或希望把不同语言的说明文档分开管理时,单一readme字段就力不从心。Poetry 为此提供了多个 README 文件的支持:通过tool.poetry.readme列表声明一组文档,构建时将它们合并进发行版的元数据与产物中。本文以仓库中的with_multiple_readme_files测试夹具为锚点,完整讲解多 README 的配置写法、底层源码实现、poetry check校验以及构建后 sdist/wheel 中的实际验证方法,帮助你在真实项目中放心使用这一能力。

一、为什么要支持多个 README 文件

PyPI 与大多数打包工具只接受单个「长描述」(即元数据中的Description字段,等价于 setuptools 的long_description)。但真实项目经常遇到这类诉求:

  • README 与 CHANGELOG 分开维护:README 面向使用方保持稳定,CHANGELOG 随版本频繁更新;
  • 多语言文档:README 按语言拆分为多个文件;
  • 文档目录化组织:把 README 拆进docs/目录按主题管理。

Poetry 的解法不是让用户自己拼字符串,而是允许在tool.poetry段用列表声明多个 README 路径,构建时按顺序拼接。仓库中的测试夹具 tests/fixtures/with_multiple_readme_files 就是这一特性的最小演示:README-1.rst内容为Single Python(标题占位),README-2.rst内容为Changelog,两者通过pyproject.toml中的列表声明组合为一个包的文档。

二、配置方式:两种表段,两种语义

Poetry 中与 README 相关的配置出现在两个地方,语义不同,需要注意区分。

1.[project]表段:单个 README(PEP 621 标准字段)

标准project表段下,readme只能是一个字符串路径或内联内容:

[project] name = "my-package" version = "0.1" readme = "README.md"

局限project.readme本身不支持列表。若希望在该标准字段下使用多个文件,必须把readme声明为动态字段,再在tool.poetry段提供实际列表(详见 docs/pyproject.md):

[project] name = "my-package" # ... dynamic = ["readme"] [tool.poetry] # ... readme = ["docs/README1.md", "docs/README2.md"]

2.[tool.poetry]表段:字符串或列表

tool.poetry.readme可以是一个路径字符串,也可以是一组路径的列表。官方文档明确建议:如果不需要多文件,优先使用project.readme;只有多 README 场景才使用tool.poetry段的列表形式(见 docs/pyproject.md)。

列表写法如下:

[tool.poetry] name = "my-package" version = "0.1" readme = ["README-1.rst", "README-2.rst"]

仓库夹具 tests/fixtures/with_multiple_readme_files/pyproject.toml 即采用这种形式,并配合poetry-core作为构建后端:

[tool.poetry] name = "my-package" version = "0.1" description = "Some description." authors = [ "Your Name <you@example.com>" ] license = "MIT" readme = [ "README-1.rst", "README-2.rst" ] [tool.poetry.dependencies] python = "^3.7" [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api"

路径基准:README 路径隐含地相对于pyproject.toml所在目录解析,因此可以放心写docs/README1.md这类子目录路径。

三、源码级解析:readme 列表是如何被处理与回写的

1. 序列化回写:src/poetry/factory.py

从源码结构看,Factory在把包对象还原为pyproject.toml内容时,会遍历package.readmes列表,将其转换为相对root_dir的 POSIX 路径并写回content["readme"]

readmes = [] for readme in package.readmes: readme_posix_path = readme.as_posix() with contextlib.suppress(ValueError): if package.root_dir: readme_posix_path = readme.relative_to(package.root_dir).as_posix() readmes.append(readme_posix_path) if readmes: content["readme"] = readmes

对应实现见 src/poetry/factory.py。这段逻辑说明:无论用户在配置里写的是相对路径还是绝对路径,Poetry 都会统一归一化为相对pyproject.toml的路径再回写,保证配置的可移植性。

2. 存在性校验:poetry check命令

poetry check会实际校验 README 文件是否存在。_validate_readme方法把字符串形式的单一 README 统一包装成列表后逐一检查(见 src/poetry/console/commands/check.py):

def _validate_readme(self, readme: str | list[str], poetry_file: Path) -> list[str]: """Check existence of referenced readme files""" readmes = [readme] if isinstance(readme, str) else readme for name in readmes: # ... 检查文件存在性,缺失则记录错误

校验逻辑同时覆盖[tool.poetry]段的readme[project]段的readme(支持字符串或{"file": ...}字典形式)。因此,配置多 README 后先跑一次poetry check,能第一时间发现路径写错或文件缺失的问题。

3. 新项目默认生成:src/poetry/layouts/layout.py

poetry new在创建项目时,会根据--readme选项(默认md)生成对应的 README 文件,并写入pyproject.tomlreadme字段(见 src/poetry/layouts/layout.py)。这意味着多 README 通常是在项目演进过程中手动改造配置,而非新建时直接生成。

四、构建行为验证:多个 README 是否真的进入发行包

配置完成后,最关心的问题是:多个 README 会不会真正进入构建产物?仓库的测试用例给出了明确答案。

tests/console/commands/test_build.py中的test_build_with_multiple_readme_files(见 tests/console/commands/test_build.py)完整演示了验证流程:

  1. 复制with_multiple_readme_files夹具到临时目录;
  2. Factory().create_poetry(...)加载项目并执行build命令;
  3. 断言dist/下同时生成 sdist(my_package-0.1.tar.gz)与 wheel(my_package-0.1-*.whl);
  4. 打开 sdist 压缩包,断言其中同时包含两个文件
with tarfile.open(sdist_file) as tf: sdist_content = tf.getnames() assert "my_package-0.1/README-1.rst" in sdist_content assert "my_package-0.1/README-2.rst" in sdist_content

同时,tests/masonry/builders/test_editable_builder.py 中也有对应的with_multiple_readme_files夹具,用于验证可编辑安装(editable install)场景下多个 README 的处理。

你可以复现的验证步骤(在任意本地 Poetry 项目中):

# 1. 在 pyproject.toml 中声明多个 README # readme = ["README-1.rst", "README-2.rst"] # 2. 校验配置与文件存在性 poetry check # 3. 构建发行包 poetry build # 4. 查看 sdist 内容,确认两个 README 都已打包 tar -tzf dist/my_package-0.1.tar.gz

五、合并规则与元数据细节

1. 元数据拼接

多个 README 的内容会被用来填充发行版元数据的Description字段(对应 PyPI 上的长描述,等价于 setuptools 的long_description)。官方文档明确:当指定多个文件时,它们按声明顺序用换行符拼接(见 docs/pyproject.md)。因此列表顺序就是最终文档的呈现顺序,请把「主说明」放在前面、「附录/变更记录」放在后面。

2. 格式与发布建议

  • README 文件可以是任意格式(Markdown、reStructuredText 等),但若打算发布到 PyPI,建议遵循 PyPI-friendly README 的推荐写法;
  • 如果希望在 sdist 之外、把 README 同时用于 wheel 的元数据展示,多文件拼接后的整体内容都会进入Description字段;
  • 测试夹具中的README-1.rstREADME-2.rst分别使用 reStructuredText 标题语法,说明不同文件可以采用同一格式混合使用。

3. 大小写敏感的跨平台注意事项

官方文档特别提醒(见 docs/pyproject.md):路径是否大小写敏感遵循平台默认行为,但建议保持大小写一致。例如在 macOS/Windows 上可以写readme = "rEaDmE.mD"匹配README.md,但 Linux 用户克隆仓库后执行poetry install会因大小写敏感而失败。多 README 场景下,务必确保配置中的路径与磁盘上的实际文件名大小写完全一致

六、最佳实践小结

结合配置文档与仓库实现,使用 Poetry 多 README 功能时建议遵循以下要点:

  1. 单文件优先用[project]:只有一个 README 时,写在project.readme;只有需要多文件时才启用dynamic = ["readme"]配合tool.poetry.readme列表;
  2. 路径相对pyproject.toml:所有路径按隐含规则相对项目根目录解析,用docs/子目录组织多份文档更清晰;
  3. 顺序即展示顺序:多个文件按列表顺序以换行拼接成最终Description,重要内容放前面;
  4. 提交前跑poetry check:利用其 README 存在性校验避免打包后才发现文件缺失;
  5. 构建后核验产物:用poetry build+tar -tzf检查 sdist 内是否同时包含全部 README,参考 tests/console/commands/test_build.py 中的断言方式;
  6. 注意大小写与格式:保持路径大小写一致以保证 Linux 上可安装,并在发布前确认长描述渲染效果。

通过readme列表,Poetry 让「一份文档」的模型平滑扩展为「一组文档」,既保持了 PEP 621 标准的兼容性,又为多语言、多主题的文档组织提供了原生支持。本文涉及的夹具 README-1.rst、README-2.rst 与 pyproject.toml 可直接作为最小可运行示例,配合 docs/pyproject.md 与 docs/basic-usage.md 一起阅读,即可完整掌握这一能力。

【免费下载链接】poetryPython packaging and dependency management made easy项目地址: https://gitcode.com/GitHub_Trending/po/poetry

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 20:27:30

MemTest86内存检测工具使用全指南

1. 为什么我们需要专业的内存测试工具刚装好的新电脑频繁蓝屏&#xff1f;游戏打到一半突然卡死&#xff1f;这些看似随机的系统不稳定现象&#xff0c;很可能就是内存条在作祟。作为计算机系统中负责临时数据存储的关键部件&#xff0c;内存的健康状况直接影响着整机稳定性。不…

作者头像 李华
网站建设 2026/9/10 20:26:58

<Skill title>

【免费下载链接】oh-my-codex OmX - Oh My codeX: Your codex is not alone. Add hooks, agent teams, HUDs, and so much more. 项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-codex Purpose What durable, codebase-specific outcome does this skill pro…

作者头像 李华
网站建设 2026/9/10 20:26:49

注意避坑!并非所有 AI 都适合写论文,2026 导师信赖工具清单

每一年毕业季&#xff0c;无数同学深陷论文难题&#xff1a;开题毫无思路、搭建框架耗费数日、初稿逻辑松散、查重标红泛滥、AI检测超标、格式反复被导师驳回。现如今市面上通用型AI工具遍地开花&#xff0c;但绝大多数通用大模型存在编造虚假参考文献、学术语句口语化、AI生成…

作者头像 李华
网站建设 2026/9/10 20:23:08

RummaGEO 使用指南:借助 GEO 基因表达签名实现基因集富集检索

RummaGEO 使用指南&#xff1a;借助 GEO 基因表达签名实现基因集富集检索 【免费下载链接】scientific-agent-skills Turn any AI agent into an AI Scientist. The #1 Agent Skills library for science, used by 190,000 scientists worldwide. 165 ready-to-use validated s…

作者头像 李华
网站建设 2026/9/10 20:17:56

短视频垂类运营:从李亚鹏案例看内容破圈方法论

1. 现象级案例背后的垂类运营逻辑李亚鹏在视频号平台连续3条内容登顶热榜第一的案例&#xff0c;已经成为短视频内容运营的经典教材。这个案例最值得玩味的地方在于&#xff1a;一个传统认知中的"过气明星"&#xff0c;如何在没有流量加持的情况下&#xff0c;仅凭内…

作者头像 李华