licenseproof
Your package has a license. Your wheel doesn't say so.
Real case, still reproducible today:
protocolbuffers/protobuf#29440.
The protobuf-7.36.0 wheel's METADATA says License: 3-Clause BSD License —
free text, not an SPDX expression — and carries no License-Expression field
at all (Metadata-Version 2.1). To be precise: the wheel does ship a
dist-info/LICENSE file, so this is "missing License-Expression (PEP 639)",
not "no license at all". A previous fix attempt (#9441) didn't fully fix it;
the issue is still open. Any compliance tooling that keys on SPDX expressions
sees this wheel as unparseable.
A sharper flavor of the same disease:
ag-ui-protocol/ag-ui#1927 —
the ag_ui_strands-0.1.9 wheel has License: None, no License-Expression,
no License-File, and zero license files anywhere in the archive. The
monorepo root is MIT-licensed, but the published artifact inherits none of it
(the hatch wheel config only includes src/). Compliance scanners flag it
"unknown license", which blocks enterprise adoption outright.
licenseproof checks that a published Python artifact actually carries usable license information — the release-integrity question nobody's CI asks.
This is deliberately not a generic license scanner (pip-licenses, ScanCode already cover that). It answers one narrow question: does this wheel/sdist contain license metadata and license text a compliance tool can use?
Part of the release-integrity series: readmeta (did your README render?), wheeltruth (did your wheel ship complete?), casecrash (will your filenames survive checkout?), tagtruth (does the tag match the release?), wheelreach (can your Python actually install it?), entryprobe (does the installed CLI actually start?), licenseproof (does the artifact say what license it's under?).
Quickstart
pip install licenseproof # PyPI upload pending rate limits; from source meanwhile:
# git clone https://github.com/hahahahahahahahah6/licenseproof && pip install ./licenseproof
licenseproof check --wheel dist/mypackage-1.0-py3-none-any.whl
source: dist/mypackage-1.0-py3-none-any.whl
verdict: LEGACY_LICENSE
detail: License: 'MIT' (free text, not SPDX); no License-Expression (PEP 639)
clean (legacy license info is a warning; use --require-spdx to fail)
licenseproof check --sdist dist/mypackage-1.0.tar.gz
licenseproof check --package mypackage # installed distribution
licenseproof check --wheel dist/x.whl --require-spdx
licenseproof check --wheel dist/x.whl --format json
Exit codes: 0 clean, 1 problems found, 2 errors (unreadable artifact, bad args).
Verdicts
| Verdict | Meaning | Fails? |
|---|---|---|
LICENSE_OK |
a License-Expression field is present (presence only — the expression is not semantically validated against the SPDX list); any License-File references exist in the dist |
no |
LEGACY_LICENSE |
only old-style license info — free-text License: field, trove classifiers, and/or undeclared license text files; no License-Expression |
only with --require-spdx |
MISSING_LICENSE |
no license metadata and no license text files in the dist | yes |
LICENSE_FILE_MISSING |
License-File metadata references files absent from the dist |
yes |
Design notes:
LEGACY_LICENSEis a warning by default, not a failure. Most of PyPI predates PEP 639; failing every one of them would be noise, not signal.--require-spdxis the strict mode for projects that have decided to move.- A
License:field containingUNKNOWN(or blank) counts as absent — that's setuptools' default, not information. License-Filevalues are matched explicitly by layout: wheels/installed dists expect them under*.dist-info/licenses/(PEP 639) or legacy*.dist-info/; sdists expect them project-root-relative under the top-level<name>-<version>/directory. No basename-only fallbacks, no..escapes.- An unparseable situation is never a silent pass: a
License-Filereference that matches nothing is its own failing verdict, not ignored.
What licenseproof does not verify
It checks the presence and machine-readability of license information, not
its meaning. A passing result confirms that the expected license metadata
fields and referenced files are present — License-Expression is checked for
presence, but SPDX identifiers and expressions are not semantically validated.
It does not interpret license compatibility (can MIT depend on GPL?) or offer
any legal interpretation. For "what does this license obligate me to do",
use a real compliance tool — licenseproof just makes sure the artifact gives
that tool something to work with.
Metadata
Release files for licenseproof 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| licenseproof-0.1.1.tar.gz | 13.9 kB | Without provenance | Details for licenseproof-0.1.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| licenseproof-0.1.1-py3-none-any.whl | Python 3 | none | any | Details for licenseproof-0.1.1-py3-none-any.whl |
Total release size: 24.5 kB
Release files / licenseproof-0.1.1.tar.gz
| Download URL | licenseproof-0.1.1.tar.gz |
|---|---|
| Size | 13.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c7c6f1585a1af91ae81bde4c863460db4dd76fb368c7c6d22784b62f2ea0d37e
|
|
BLAKE2b-256 checksum How to use checksums |
ef10f21c09a9d969dd8512c1c38886c16857be0a1d6a0b937d7ac65d4b497ab4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|
Release files / licenseproof-0.1.1-py3-none-any.whl
| Download URL | licenseproof-0.1.1-py3-none-any.whl |
|---|---|
| Size | 10.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
51f9bebbe8c08842e08ea0a9d2d393a76c844e772803504652d3561b3990521b
|
|
BLAKE2b-256 checksum How to use checksums |
28044faa2f7167a47760ae8ffbb249fee42042b75e5770c6b591549670a28083
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|
Security for licenseproof 0.1.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.