bazel-contrib / bazel-contrib/rules_python

py_wheel: support PEP 639 license metadata (License-Expression / License-File)

オープン
#4,042 コメント 6 件 リアクション 0 件 担当者 0 名 GitHub で見る
Good first issue help wanted
主要言語
Starlark
スター
688
フォーク
721
平均マージ
15時間 7分
マージ済み PR(30日)
76

説明

# 🚀 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 `-.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-File`s 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.

```python
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.

コントリビューションガイド

コントリビューションガイドを開く

調査の方向性

python/private/py_wheel.bzl から始め、特に 250 行目付近の license 属性と、422 行目および 432 行目付近のメタデータ生成を確認してください。既存の extra_distinfo_files がどのようにパッケージ化されているかを追跡し、そのうえで要求された PEP 639 属性を実装し、Metadata-Version、License-Expression、License-File、および .dist-info/licenses/ 配下のファイルが issue の例と一致することを確認してください。その際、既存の動作は維持してください。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
python
領域
build-system
issue の種類
機能追加
難易度
4/5
見積もり時間
3〜5日
活発さ
活発
明瞭さ
明確に書かれている
初心者へのやさしさ
63/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。