add support for PEP 639 License Clarity#870
Conversation
Reviewer's GuideThis PR implements full support for PEP 639 “License Clarity” by extending the core factory to parse new [project].license-files globs and SPDX license expressions, enhancing strict validation, bumping core metadata to 2.4, updating masonry builders to emit License-Expression and License-File fields and embed license files under dist-info/licenses, and updating/adding tests to cover all new scenarios. Sequence Diagram: PEP 639 License ProcessingsequenceDiagram
actor Developer
participant P as PyProjectTOML
participant F as Factory
participant PP as ProjectPackage
participant M as Metadata
participant B as Builder
Developer->>P: Defines [project].license (SPDX)\nand [project].license-files
F->>P: Reads pyproject.toml data
F->>PP: _configure_package_metadata(package, project_data)
activate F
F->>F: canonicalize_license_expression(project_data["license"])
PP->>PP: set package.license_expression
F->>F: Validate license-files globs
PP->>PP: set package.license_files (globs)
deactivate F
F->>F: validate(toml_data)
activate F
F->>F: _validate_project(project_data, result) // Validates SPDX, warns on legacy
deactivate F
M->>PP: from_package(package)
activate M
M->>M: set meta.metadata_version = "2.4"
M->>M: set meta.license_expression (from package.license_expression)
M->>PP: Processes package.license_files (globs from package.root_dir)
activate PP
PP->>PP: package.root_dir.glob(pattern)
deactivate PP
opt Globs match no files
M->>M: Raise RuntimeError
end
M->>M: set meta.license_files (resolved relative paths)
deactivate M
B->>M: get_metadata_content()
activate B
B->>B: Writes Metadata-Version: 2.4
opt meta.license_expression is set
B->>B: Writes License-Expression: ...
end
loop for each license_file in meta.license_files
B->>B: Writes License-File: ...
end
deactivate B
B->>M: _get_legal_files()
activate B
B->>B: Returns files based on meta.license_files
deactivate B
B->>B: Includes license files (e.g., in dist-info/licenses/)
Class Diagram: PEP 639 License Handling ChangesclassDiagram
direction LR
class Factory {
+String _configure_package_metadata(ProjectPackage package, dict project, dict tool_poetry, Path root)
+None _validate_project(dict project, dict result)
}
class ProjectPackage {
+license_expression: NormalizedLicenseExpression
+license_files: LicenseFileConfig
+List~String~ all_classifiers()
}
class Metadata {
+String metadata_version = "2.4"
+String license_expression
+Tuple~String~ license_files
+Metadata from_package(ProjectPackage package)
}
class Builder {
#Metadata _meta
+String get_metadata_content()
#Set~Path~ _get_legal_files()
}
class WheelBuilder {
+Path prepare_metadata(Path metadata_directory)
}
Factory ..> ProjectPackage : configures
Metadata ..> ProjectPackage : generated from
Builder ..> Metadata : uses
WheelBuilder --|> Builder
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
Wow, all this code only for parsing new license fields? |
And we do not even do the SPDX parsing by ourselves but use |
|
I noticed, thanks for all the work! |
There was a problem hiding this comment.
Hey @radoering - I've reviewed your changes - here's some feedback:
- The new license parsing logic in Factory._configure_package_metadata is deeply nested—consider breaking it into smaller helper methods to improve readability and maintainability.
- Metadata.from_package and Builder._get_legal_files share very similar license‐file discovery code—extract that into a common utility to avoid duplication.
- The parameterized license tests are quite verbose and repetitive—introduce helper fixtures or functions to encapsulate common setup and assertions.
Here's what I looked at during the review
- 🟡 General issues: 2 issues found
- 🟢 Security: all looks good
- 🟡 Testing: 1 issue found
- 🟢 Documentation: all looks good
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
This PR contains the following updates: | Package | Update | Change | |---|---|---| | [poetry](https://github.com/python-poetry/poetry) ([changelog](https://python-poetry.org/history/)) | minor | `2.1.4` -> `2.2.1` | --- ### Release Notes <details> <summary>python-poetry/poetry (poetry)</summary> ### [`v2.2.1`](https://github.com/python-poetry/poetry/blob/HEAD/CHANGELOG.md#221---2025-09-21) [Compare Source](python-poetry/poetry@2.2.0...2.2.1) ##### Fixed - Fix an issue where `poetry self show` failed with a message about an invalid output format ([#​10560](python-poetry/poetry#10560)). ##### Docs - Remove outdated statements about dependency groups ([#​10561](python-poetry/poetry#10561)). ##### poetry-core ([`2.2.1`](https://github.com/python-poetry/poetry-core/releases/tag/2.2.1)) - Fix an issue where it was not possible to declare a PEP 735 dependency group as optional ([#​888](python-poetry/poetry-core#888)). ### [`v2.2.0`](https://github.com/python-poetry/poetry/blob/HEAD/CHANGELOG.md#220---2025-09-14) [Compare Source](python-poetry/poetry@2.1.4...2.2.0) ##### Added - **Add support for nesting dependency groups** ([#​10166](python-poetry/poetry#10166)). - **Add support for PEP 735 dependency groups** ([#​10130](python-poetry/poetry#10130)). - **Add support for PEP 639 license clarity** ([#​10413](python-poetry/poetry#10413)). - Add a `--format` option to `poetry show` to alternatively output json format ([#​10487](python-poetry/poetry#10487)). - Add official support for Python 3.14 ([#​10514](python-poetry/poetry#10514)). ##### Changed - **Normalize dependency group names** ([#​10387](python-poetry/poetry#10387)). - Change `installer.no-binary` and `installer.only-binary` so that explicit package names will take precedence over `:all:` ([#​10278](python-poetry/poetry#10278)). - Improve log output during `poetry install` when a wheel is built from source ([#​10404](python-poetry/poetry#10404)). - Improve error message in case a file lock could not be acquired while cloning a git repository ([#​10535](python-poetry/poetry#10535)). - Require `dulwich>=0.24.0` ([#​10492](python-poetry/poetry#10492)). - Allow `virtualenv>=20.33` again ([#​10506](python-poetry/poetry#10506)). - Allow `findpython>=0.7` ([#​10510](python-poetry/poetry#10510)). - Allow `importlib-metadata>=8.7` ([#​10511](python-poetry/poetry#10511)). ##### Fixed - Fix an issue where `poetry new` did not create the project structure in an existing empty directory ([#​10431](python-poetry/poetry#10431)). - Fix an issue where a dependency that was required for a specific Python version was not installed into an environment of a pre-release Python version ([#​10516](python-poetry/poetry#10516)). ##### poetry-core ([`2.2.0`](https://github.com/python-poetry/poetry-core/releases/tag/2.2.0)) - Deprecate table values and values that are not valid SPDX expressions for `[project.license]` ([#​870](python-poetry/poetry-core#870)). - Fix an issue where explicitly included files that are in `.gitignore` were not included in the distribution ([#​874](python-poetry/poetry-core#874)). - Fix an issue where marker operations could result in invalid markers ([#​875](python-poetry/poetry-core#875)). </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MS42MC40IiwidXBkYXRlZEluVmVyIjoiNDEuNjAuNCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==--> Reviewed-on: https://git.walbeck.it/walbeck-it/docker-python-poetry/pulls/1588 Co-authored-by: renovate-bot <[email protected]> Co-committed-by: renovate-bot <[email protected]>
Related to: python-poetry/poetry#9670
Downstream tests will be fixed in python-poetry/poetry#10413 after merging this one.
Summary by Sourcery
Implement PEP 639 license clarity support by adding parsing and validation for project.license-files and SPDX license expressions, bump core metadata version to 2.4, include license data in distributions, and deprecate legacy license tables and classifiers.
New Features:
Bug Fixes:
Enhancements:
Tests: