Skip to content

✨ feat(build): publish a third-party notices file - #3266

Merged
gaborbernat merged 1 commit into
pypa:mainfrom
gaborbernat:third-party-notices
Sep 19, 2026
Merged

gaborbernat merged 1 commit into
pypa:mainfrom
gaborbernat:third-party-notices

Conversation

@gaborbernat

Copy link
Copy Markdown
Contributor

virtualenv already satisfies its MIT obligations. 📄 Every embedded pip and setuptools wheel carries its own MIT notice inside its own .dist-info/licenses/ directory, and virtualenv redistributes that wheel unmodified, notice included. What was missing was discoverability, not compliance: nothing at the top level told a downstream auditor those notices existed or where to find them without unzipping a bundled wheel to check.

tasks/upgrade_wheels.py now writes THIRD-PARTY-NOTICES.md alongside embed/__init__.py, reading the same BUNDLE_SHA256 table so a wheel bump keeps it current with no separate update step. Only the licence of the wheel virtualenv itself redistributes gets reproduced; whatever that wheel in turn vendors already carries its own licence inside it, so duplicating those at the top level would only add churn on every bump for no benefit. Identical licence text across bundled versions of the same package collapses into one section listing every matching filename, which is why pip-26.0.1 and pip-26.2.1 share a section today.

LICENSE itself stays untouched. GitHub's own guidance warns that a licence file complicated by appended text can stop its detector from naming a licence at all, showing "View license" in the sidebar instead, which is exactly what happens on projects that append third-party text to their own LICENSE. The notices live in a separate file and are declared alongside LICENSE through PEP 639 license-files rather than folded into it.

A unit test asserts every currently bundled distribution has a section in the checked-in file, so a wheel bump that forgets to regenerate it fails loudly instead of silently drifting.

virtualenv already satisfies its MIT obligations: every embedded pip
and setuptools wheel carries its own MIT notice inside its own
.dist-info/licenses/ directory, redistributed unmodified. What was
missing was discoverability, not compliance - nothing at the top
level told a downstream auditor those notices existed or where to
find them without unzipping a bundled wheel to check.

tasks/upgrade_wheels.py now writes THIRD-PARTY-NOTICES.md alongside
embed/__init__.py, reading the same BUNDLE_SHA256 table so a wheel
bump keeps it current with no separate update step. Only the licence
of the wheel virtualenv itself redistributes is reproduced; whatever
that wheel in turn vendors already carries its own licence inside it
and stays there rather than being duplicated at the top level.
Identical licence text across bundled versions of the same package
collapses into one section listing every matching filename.

LICENSE itself is untouched. Appending third-party text to it is
what breaks GitHub's own licence detection on repositories that try
it, so the notices live in a separate file instead and are declared
alongside LICENSE through PEP 639 license-files rather than folded
into it.

The regression test locates THIRD-PARTY-NOTICES.md relative to its
own file rather than through BUNDLE_FOLDER: a non-editable install
puts the installed package under site-packages with no relationship
to the checkout, so deriving the repo root from the installed
package's own runtime path only worked by coincidence in an editable
dev environment and failed outright under CI's real install.
@gaborbernat
gaborbernat merged commit 3e95492 into pypa:main Sep 19, 2026
64 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant