check_license_metadata¶
rhiza_hooks.check_license_metadata
¶
Check that pyproject.toml does not declare its licence twice over.
Declaring both a PEP 639 license expression and a legacy
License :: OSI Approved :: … trove classifier is not merely redundant — it makes
the project unbuildable. setuptools>=77 refuses outright:
License classifiers have been superseded by license expressions … Please remove
and uv_build warns. The two are therefore mutually exclusive in practice, and the
failure shows up at build or publish time rather than at the commit that caused it.
This is a live problem in this ecosystem: rhiza's own synced test
test_license_classifier_present still asserts the trove classifier through
template v1.2.1, which makes it unsatisfiable for exactly the PEP 639 layout
/rhiza:license produces (filed upstream as jebel-quant/rhiza#1440). A hook cannot
fix the upstream test, but it can stop the broken combination reaching a build.
Only the combination is an error. Either form alone is fine, and so is the
pre-PEP-639 table form (license = {file = "LICENSE"}) alongside a classifier —
that combination is valid legacy metadata, and rejecting it would fail projects that
have not migrated and do not need to.
Validating the SPDX expression's syntax is deliberately out of scope: that needs a license-expression library, and the value here is the rule that breaks builds.
Exit codes
0 - licence metadata is coherent 1 - both forms are declared (or, with --require-license, neither is)
check_license_metadata(repo_root, require_license=False)
¶
Check the licence metadata in pyproject.toml.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
repo_root
|
Path
|
Root directory of the repository. |
required |
require_license
|
bool
|
Also report a project that declares no licence at all. |
False
|
Returns:
| Type | Description |
|---|---|
list[str]
|
List of error messages (empty when the metadata is coherent). |
Source code in rhiza_hooks/check_license_metadata.py
license_classifiers(project)
¶
Return the License :: … trove classifiers declared in [project].
Source code in rhiza_hooks/check_license_metadata.py
main(argv=None)
¶
Run the hook and return a process exit code.
Source code in rhiza_hooks/check_license_metadata.py
spdx_expression(project)
¶
Return the PEP 639 SPDX license expression, if that is the form in use.
PEP 639 makes license a string. The older table forms
({file = …} / {text = …}) are not SPDX expressions and do not conflict
with a classifier, so they read as absent here.