π feature request
Relevant Rules
py_wheel (python/private/py_wheel.bzl) β extending an existing rule.
Description
py_wheel cannot produce a wheel whose METADATA conforms to PEP 639, which is now Final.
On main today:
Metadata-Version is hardcoded to 2.1 (python/private/py_wheel.bzl:422); the PEP 639 fields require 2.4.
- The only license-related attribute is the legacy free-text
license (:250), emitted as the License: field (:432). PEP 639 deprecates that field.
- There is no way to emit
License-Expression, no way to emit License-File, and no way to place license texts under <name>-<version>.dist-info/licenses/.
- There is no escape hatch for appending arbitrary
METADATA lines either, so this cannot be worked around from a BUILD file.
The practical impact is that a py_wheel cannot declare its license as an SPDX expression, and cannot ship the license texts of its bundled third-party dependencies in the location PEP 639 defines. For anyone who has to produce auditable license metadata for a redistributed wheel, that is a hard blocker.
Other backends have already moved: setuptools 77.0.0 emits License-Expression, stores License-Files in .dist-info/licenses/, and bumps core metadata to 2.4.
Describe the solution you'd like
Two new attributes on py_wheel:
license_expression (string) β an SPDX license expression, emitted as License-Expression.
license_files (label-keyed string dict) β license file targets mapped to their destination path relative to .dist-info/licenses/. Each entry emits one License-File line and packages the file at that path.
Metadata-Version would be raised to 2.4 only when one of the two is set, so existing users are unaffected and the change stays backwards compatible. license and license_expression would be mutually exclusive, as PEP 639 intends.
py_wheel(
name = "my_wheel",
distribution = "my_package",
version = "1.0.0",
license_expression = "Apache-2.0 AND MIT",
license_files = {
"//:LICENSE": "LICENSE",
"//third_party:some_dep_license.txt": "third_party/some_dep.txt",
},
)
produces:
Metadata-Version: 2.4
Name: my_package
Version: 1.0.0
License-Expression: Apache-2.0 AND MIT
License-File: LICENSE
License-File: third_party/some_dep.txt
with both files packaged under my_package-1.0.0.dist-info/licenses/.
Describe alternatives you've considered
- The legacy
license attribute β deprecated by PEP 639, carries no SPDX semantics, and does not package license files at all.
extra_distinfo_files β can place files inside .dist-info/, but Metadata-Version stays 2.1 and no License-File lines are emitted. The files end up present but undeclared, which is not PEP 639 conformant.
- Post-processing the built wheel in a separate rule β means unzipping and rezipping the artifact just to rewrite
METADATA; awkward, and easy to get wrong for reproducibility.
- Carrying a local patch to
python/private/py_wheel.bzl β what we do today. It works, but it has to be rebased on every rules_python bump, which is exactly what we would rather not carry.
I have this implemented and working locally and would be glad to send a PR. I need to clear the CLA on my employer's side first, so I am opening the issue now to check whether the approach and the attribute shape are acceptable before going down that route.
π feature request
Relevant Rules
py_wheel(python/private/py_wheel.bzl) β extending an existing rule.Description
py_wheelcannot produce a wheel whoseMETADATAconforms to PEP 639, which is now Final.On
maintoday:Metadata-Versionis hardcoded to2.1(python/private/py_wheel.bzl:422); the PEP 639 fields require2.4.license(:250), emitted as theLicense:field (:432). PEP 639 deprecates that field.License-Expression, no way to emitLicense-File, and no way to place license texts under<name>-<version>.dist-info/licenses/.METADATAlines either, so this cannot be worked around from aBUILDfile.The practical impact is that a
py_wheelcannot declare its license as an SPDX expression, and cannot ship the license texts of its bundled third-party dependencies in the location PEP 639 defines. For anyone who has to produce auditable license metadata for a redistributed wheel, that is a hard blocker.Other backends have already moved: setuptools 77.0.0 emits
License-Expression, storesLicense-Files in.dist-info/licenses/, and bumps core metadata to 2.4.Describe the solution you'd like
Two new attributes on
py_wheel:license_expression(string) β an SPDX license expression, emitted asLicense-Expression.license_files(label-keyed string dict) β license file targets mapped to their destination path relative to.dist-info/licenses/. Each entry emits oneLicense-Fileline and packages the file at that path.Metadata-Versionwould be raised to2.4only when one of the two is set, so existing users are unaffected and the change stays backwards compatible.licenseandlicense_expressionwould be mutually exclusive, as PEP 639 intends.produces:
with both files packaged under
my_package-1.0.0.dist-info/licenses/.Describe alternatives you've considered
licenseattribute β deprecated by PEP 639, carries no SPDX semantics, and does not package license files at all.extra_distinfo_filesβ can place files inside.dist-info/, butMetadata-Versionstays2.1and noLicense-Filelines are emitted. The files end up present but undeclared, which is not PEP 639 conformant.METADATA; awkward, and easy to get wrong for reproducibility.python/private/py_wheel.bzlβ what we do today. It works, but it has to be rebased on everyrules_pythonbump, which is exactly what we would rather not carry.I have this implemented and working locally and would be glad to send a PR. I need to clear the CLA on my employer's side first, so I am opening the issue now to check whether the approach and the attribute shape are acceptable before going down that route.