Skip to content

Declare the license as an SPDX expression instead of a file - #980

Open
sap1110 wants to merge 1 commit into
ipython:mainfrom
sap1110:license-metadata-spdx
Open

Declare the license as an SPDX expression instead of a file#980
sap1110 wants to merge 1 commit into
ipython:mainfrom
sap1110:license-metadata-spdx

Conversation

@sap1110

@sap1110 sap1110 commented Aug 17, 2026

Copy link
Copy Markdown

Closes #870

license = {file = "LICENSE"} tells the build backend to inline the entire license text into the License: field of METADATA. The reporter saw the effect on PyPI, which prints that field where the short license name belongs.

Building main today still reproduces it. The License: field in the wheel spans 30 lines:

Metadata-Version: 2.5
License: BSD 3-Clause License
        <28 more lines of BSD text>
License-File: LICENSE

The PEP 639 form declares the license as an SPDX expression, which is what the field was meant to hold:

Metadata-Version: 2.5
License-Expression: BSD-3-Clause
License-File: LICENSE

The LICENSE file itself is still shipped, now under traitlets-<version>.dist-info/licenses/LICENSE, via license-files.

Two changes come along with it. The License :: OSI Approved :: BSD License classifier is removed, since PEP 639 deprecates license classifiers once an expression is declared and some backends reject having both. And the hatchling floor moves from 1.5 to 1.27, the first release that understands license-files and emits License-Expression; below that the new fields would be silently dropped.

The reporter wondered whether a custom packaging script was involved. It isn't, this is just the older license = {file = ...} spelling behaving as it was defined to.


🤖🍆 Prepared with the help of an AI coding agent, marked as the contributing guide asks agents to do. Reviewed and tested by me.

license = {file = "LICENSE"} makes the backend inline the whole license text
into the METADATA License field, so the built wheel carries a 30-line License
field and PyPI renders the full BSD text where the short name belongs.

Switching to the PEP 639 form emits License-Expression: BSD-3-Clause instead.
The LICENSE file is still shipped, at dist-info/licenses/LICENSE, via
license-files.

The License :: OSI Approved :: BSD License classifier goes with it, since PEP
639 deprecates license classifiers once an expression is declared, and hatchling
is floored at 1.27, the first release that understands these fields.

🤖🍆 Prepared with the help of an AI coding agent, marked as the contributing
guide asks agents to do. Reviewed and tested by me.
@codecov

codecov Bot commented Aug 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.14%. Comparing base (80756bf) to head (0e0dcc7).

Components Coverage Δ
traitlets 85.50% <ø> (ø)
tests 99.06% <ø> (ø)

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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.

Fix License metadata in PyPi package

1 participant