Skip to content

Support parent-relative pyproject metadata in sdists#3182

Merged
messense merged 6 commits into
mainfrom
copilot/fix-sdist-installation-issue
May 13, 2026
Merged

Support parent-relative pyproject metadata in sdists#3182
messense merged 6 commits into
mainfrom
copilot/fix-sdist-installation-issue

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 11, 2026

Fixes #3181.

When pyproject.toml lives in a Cargo workspace member, maturin sdist places pyproject.toml at the sdist root as required by the source distribution format. If PEP 621 metadata such as [project.readme] file = "../README.md" or license = { file = "../LICENSE" } points outside the member directory, the elevated pyproject.toml used to keep paths that no longer resolved from the sdist root, causing pip install <sdist> metadata generation to fail.

Changes

  • For Cargo-generated sdists, include project.readme and project.license.file metadata files referenced from pyproject.toml, including parent-relative paths that stay within the Cargo workspace.
  • Rewrite those metadata paths in the elevated root pyproject.toml so they point at the files' archive locations.
  • Keep PKG-INFO / License-File metadata aligned with the rewritten sdist layout for parent-relative project.license.file.
  • For the Git sdist generator, reject parent-relative pyproject metadata paths instead of copying extra files, so Git sdists remain faithful to git ls-files.
  • Add regression coverage for a workspace member whose pyproject.toml references parent metadata files, and for the Git-generator rejection case.

Notes

The Cargo sdist path is intentionally allowed to copy and rewrite these metadata files because it already constructs an archive layout around Cargo workspace membership and path dependencies. The Git sdist path intentionally does not do this: it should package exactly what git ls-files reports from the pyproject.toml directory, so parent-relative metadata paths are reported as unsupported there.

Copilot AI linked an issue May 11, 2026 that may be closed by this pull request
2 tasks
Copilot AI changed the title [WIP] Fix sdist installation issue in maturin project Include [project.readme] table-form file at sdist root May 11, 2026
Copilot AI requested a review from messense May 11, 2026 05:22
@messense messense requested a review from Copilot May 11, 2026 05:28
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Fixes maturin sdist for Cargo workspace members where pyproject.toml is elevated to the sdist root and [project.readme] uses the PEP 621 table form, ensuring the referenced README is also copied to the sdist root so metadata generation doesn’t fail.

Changes:

  • Extend add_pyproject_metadata to also handle ReadMe::Table { file: Some(...) } when copying README into the sdist root.
  • Add a regression test covering workspace-member pyproject.toml with table-form [project.readme].

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/source_distribution/pyproject.rs Adds support for table-form [project.readme] so the README is included at the sdist root when pyproject.toml is elevated.
tests/run/sdist.rs Adds a regression test asserting README is present at the archive root for the table-form readme case.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/source_distribution/pyproject.rs Outdated
@messense messense force-pushed the copilot/fix-sdist-installation-issue branch from da61e08 to 6c6b9da Compare May 11, 2026 13:52
@messense messense requested a review from Copilot May 11, 2026 13:52
@messense messense force-pushed the copilot/fix-sdist-installation-issue branch from 6c6b9da to db4c966 Compare May 11, 2026 13:58
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Comment thread src/source_distribution/mod.rs Outdated
Comment thread src/source_distribution/pyproject.rs
Comment thread src/source_distribution/pyproject.rs
Comment thread src/metadata.rs
@messense messense force-pushed the copilot/fix-sdist-installation-issue branch from db4c966 to 06dad83 Compare May 11, 2026 14:23
@messense messense requested a review from Copilot May 12, 2026 00:09
@messense messense changed the title Include [project.readme] table-form file at sdist root Support parent-relative pyproject metadata in sdists May 12, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Comment thread src/source_distribution/pyproject.rs
Comment thread src/metadata.rs Outdated
@messense messense force-pushed the copilot/fix-sdist-installation-issue branch from 06dad83 to 464e8c4 Compare May 12, 2026 00:47
Copilot AI and others added 6 commits May 12, 2026 21:01
When `pyproject.toml` lives in a subdirectory of a Cargo workspace,
`add_pyproject_metadata` only elevated the readme to the sdist root for
the string form (`readme = "README.md"`). The table form
(`[project.readme]` with `file = "README.md"`) was silently ignored, so
the file remained under the workspace-member subdirectory and `pip
install` of the sdist failed when generating metadata.

Handle the `ReadMe::Table { file, .. }` variant alongside
`ReadMe::RelativePath` so the readme is copied next to `pyproject.toml`
in either case.

Agent-Logs-Url: https://github.com/PyO3/maturin/sessions/c75f929a-fc52-412b-908c-644c020e442b

Co-authored-by: messense <1556054+messense@users.noreply.github.com>
Reject absolute paths and `..` traversal in the `file` values of
`[project.readme]` and `[project.license]` before adding them to the
sdist. Otherwise such paths could place files at surprising locations in
the archive or read files outside the project directory when the sdist
copies them next to `pyproject.toml`.

Agent-Logs-Url: https://github.com/PyO3/maturin/sessions/304ac3d5-d758-482b-9beb-8d13060340e7

Co-authored-by: messense <1556054+messense@users.noreply.github.com>
Combine the validate/dedupe/add steps for files referenced from
`pyproject.toml` (`project.readme.file`, `project.license.file`) into a
single `add_pyproject_relative_file` helper. Previously the call sites
duplicated the `root_dir.join` / `writer.contains_target` / `writer.add_file`
sequence, and a separate `check_pyproject_relative_path` only validated
the path.

Also collapse the `pyproject_toml::ReadMe` match into a single or-pattern
covering both `RelativePath(file)` and `Table { file: Some(file), .. }`,
and let the helper take `impl AsRef<Path>` so it accepts the readme's
`String` and the license's `PathBuf` without per-call-site conversions.

No behavior change.
Allow Cargo-generated sdists to include pyproject readme and license files that live above a workspace member, rewriting the root pyproject.toml paths to their archive locations. Reject those parent-relative metadata paths for the git sdist generator so its output remains faithful to git ls-files.
@messense messense force-pushed the copilot/fix-sdist-installation-issue branch from 464e8c4 to 2bdb8d4 Compare May 12, 2026 13:01
@messense messense marked this pull request as ready for review May 13, 2026 00:23
@messense messense merged commit af6b014 into main May 13, 2026
45 checks passed
@messense messense deleted the copilot/fix-sdist-installation-issue branch May 13, 2026 00:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

sdist fails to install when maturin project is a Cargo workspace member

3 participants