Skip to content

Conversation

@radoering
Copy link
Member

@radoering radoering commented May 31, 2025

Pull Request Check List

Requires: python-poetry/poetry-core#870
Resolves: #9670

  • Added tests for changed code (see poetry-core PR).
  • Updated documentation for changed code.

Summary by Sourcery

Implement PEP 639 support by switching to SPDX license expressions, introducing a license-files setting, deprecating table-based definitions, bumping packaging to 24.2, and updating documentation and tests to reflect these changes

New Features:

  • Introduce support for PEP 639 license expressions as the primary license field in pyproject.toml
  • Add a license-files field to specify custom license file patterns
  • Deprecate and emit warnings for table-based license definitions

Enhancements:

  • Bump the packaging dependency requirement to >=24.2 to enable PEP 639 support
  • Update internal metadata generation to emit a License-Expression header instead of License

Documentation:

  • Revise pyproject and libraries documentation to describe SPDX license expressions, default included license files, the new license-files field, and deprecated syntax

Tests:

  • Update tests and fixtures to use string-based license definitions and validate the new License-Expression metadata header
  • Add deprecation warning checks for invalid or table-based license configurations

@sourcery-ai
Copy link

sourcery-ai bot commented May 31, 2025

Reviewer's Guide

Add PEP 639 License Clarity support by simplifying license specification, introducing a license-files field with default glob patterns, deprecating table-based license syntax, and updating documentation, tests, and dependency references accordingly.

Class diagram for license specification changes in pyproject.toml

classDiagram
    class ProjectMetadata {
        +license: str
        +license_files: List[str]
    }
    ProjectMetadata : -license (table syntax) [deprecated]
    ProjectMetadata : +license (SPDX string)
    ProjectMetadata : +license_files (glob patterns)
    ProjectMetadata : +license_files = default patterns if not specified
    ProjectMetadata : +license_files = [] disables inclusion
Loading

Class diagram for updated build process including license files

classDiagram
    class Builder {
        +build_sdist()
        +build_wheel()
        +include_license_files(patterns: List[str])
    }
    Builder --> ProjectMetadata
    Builder : +include_license_files uses license_files from ProjectMetadata
    Builder : +include_license_files uses default patterns if not specified
    Builder : +include_license_files skips if patterns is empty
Loading

File-Level Changes

Change Details Files
Simplify license specification and introduce license-files field
  • Deprecate table-based license syntax in favor of simple string identifiers
  • Add license-files section with default patterns and override behavior
  • Update root project manifest to use string-based license field
docs/pyproject.md
docs/libraries.md
pyproject.toml
Update builder metadata and test assertions for license expressions
  • Replace License: header with License-Expression: in editable builder tests
  • Remove old license classifier expectation from METADATA
  • Standardize file content assertions in test_editable_builder
tests/masonry/builders/test_editable_builder.py
Add SPDX validation warnings and update related tests and fixtures
  • Introduce warning for deprecated/invalid SPDX identifiers in check command tests
  • Update invalid_pyproject fixture to use string-based license
  • Update simple_project fixture to use string-based license
tests/console/commands/test_check.py
tests/fixtures/invalid_pyproject/pyproject.toml
tests/fixtures/simple_project/pyproject.toml
Require updated packaging version for PEP 639 support
  • Bump packaging dependency to >=24.2 in project manifest
pyproject.toml

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@radoering radoering added the impact/docs Contains or requires documentation changes label May 31, 2025
@github-actions
Copy link

github-actions bot commented May 31, 2025

Deploy preview for website ready!

✅ Preview
https://website-2pqoe34nt-python-poetry.vercel.app

Built with commit 94098f6.
This pull request is being automatically deployed with vercel-action

@radoering radoering force-pushed the pep639 branch 2 times, most recently from 687a4aa to 103aa7c Compare May 31, 2025 06:13
@radoering radoering requested a review from a team June 5, 2025 03:53
@radoering radoering force-pushed the pep639 branch 2 times, most recently from f6216e5 to be62db9 Compare August 17, 2025 05:58
@radoering radoering marked this pull request as ready for review August 17, 2025 06:00
Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey there - I've reviewed your changes and they look great!

Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments

### Comment 1
<location> `tests/console/commands/test_check.py:176` </location>
<code_context>
 Error: Invalid source "not-exists" referenced in dependencies.
 Error: Invalid source "not-exists2" referenced in dependencies.
 Error: poetry.lock was not found.
+Warning: [project.license] is not a valid SPDX identifier.\
+ This is deprecated and will raise an error in the future.
 Warning: A wildcard Python dependency is ambiguous.\
  Consider specifying a more explicit one.
</code_context>

<issue_to_address>
Consider adding tests for valid SPDX license identifiers and edge cases.

Adding tests for valid identifiers and edge cases like mixed-case, extra whitespace, or multiple licenses will help ensure comprehensive coverage.
</issue_to_address>

### Comment 2
<location> `tests/masonry/builders/test_editable_builder.py:195` </location>
<code_context>

 """
-    assert metadata == dist_info.joinpath("METADATA").read_text(encoding="utf-8")
+    if project == "simple_project":
+        metadata = metadata.replace("License:", "License-Expression:").replace(
+            "Classifier: License :: OSI Approved :: MIT License\n", ""
+        )
</code_context>

<issue_to_address>
Test could be improved by explicitly checking license-files inclusion in built distributions.

Add assertions to verify that license files are present and correct in the built distribution, as specified by the license-files field.

Suggested implementation:

```python
    assert dist_info.joinpath("METADATA").read_text(encoding="utf-8") == metadata

    # Check license-files inclusion in built distribution
    import re

    # Extract license-files from metadata
    license_files = []
    license_files_match = re.search(r"license-files = \[(.*?)\]", metadata, re.DOTALL)
    if license_files_match:
        files_str = license_files_match.group(1)
        # Split and clean up file names
        license_files = [f.strip().strip('"').strip("'") for f in files_str.split(",") if f.strip()]

    # Assert each license file is present and correct in dist_info
    for license_file in license_files:
        dist_license_path = dist_info.parent.joinpath(license_file)
        source_license_path = project_dir.joinpath(license_file)
        assert dist_license_path.exists(), f"License file {license_file} missing from built distribution"
        assert dist_license_path.read_text(encoding="utf-8") == source_license_path.read_text(encoding="utf-8"), f"License file {license_file} content mismatch"

    with open(dist_info.joinpath("RECORD"), encoding="utf-8", newline="") as f:
        reader = csv.reader(f)
    sys.exit(baz.boom.bim())
"""

```

- Ensure that `project_dir` is defined and points to the source project directory containing the license files.
- If the license-files field is not in the metadata as a TOML array, adjust the regex to match the actual format.
- If the test setup uses a different way to specify license files, adapt the extraction logic accordingly.
</issue_to_address>

### Comment 3
<location> `docs/pyproject.md:121` </location>
<code_context>
+]
 ```

+Per default, Poetry will include the following files:
+- `LICENSE*`
+- `LICENCE*`
</code_context>

<issue_to_address>
Replace 'Per default' with 'By default' for correct English usage.

'Per default' is a direct translation from German and is not standard English. Please use 'By default' instead.
</issue_to_address>

<suggested_fix>
<<<<<<< SEARCH
Per default, Poetry will include the following files:
=======
By default, Poetry will include the following files:
>>>>>>> REPLACE

</suggested_fix>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@radoering radoering merged commit beadd42 into python-poetry:main Aug 17, 2025
54 checks passed
@radoering radoering mentioned this pull request Aug 27, 2025
@github-actions
Copy link

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 17, 2025
@radoering radoering deleted the pep639 branch December 13, 2025 17:15
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

impact/docs Contains or requires documentation changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement PEP 639

1 participant