Skip to content

Commit 41c807c

Browse files
committed
Show License-Expression if present in package metadata
With Core Metadata 2.4 a new field, License-Expression, has been added. If it's present, favor it over the deprecated (with PEP 639) legacy unstructured License field. Closes: #13112
1 parent 3b0215f commit 41c807c

File tree

5 files changed

+51
-2
lines changed

5 files changed

+51
-2
lines changed

news/13112.feature.rst

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Prefer to display ``License-Expression`` in ``pip show`` if metadata version is at least 2.4.

src/pip/_internal/commands/show.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ class _PackageInfo(NamedTuple):
6666
author: str
6767
author_email: str
6868
license: str
69+
license_expression: str
6970
entry_points: List[str]
7071
files: Optional[List[str]]
7172

@@ -161,6 +162,7 @@ def _get_requiring_packages(current_dist: BaseDistribution) -> Iterator[str]:
161162
author=metadata.get("Author", ""),
162163
author_email=metadata.get("Author-email", ""),
163164
license=metadata.get("License", ""),
165+
license_expression=metadata.get("License-Expression", ""),
164166
entry_points=entry_points,
165167
files=files,
166168
)
@@ -180,13 +182,18 @@ def print_results(
180182
if i > 0:
181183
write_output("---")
182184

185+
metadata_version_tuple = tuple(map(int, dist.metadata_version.split(".")))
186+
183187
write_output("Name: %s", dist.name)
184188
write_output("Version: %s", dist.version)
185189
write_output("Summary: %s", dist.summary)
186190
write_output("Home-page: %s", dist.homepage)
187191
write_output("Author: %s", dist.author)
188192
write_output("Author-email: %s", dist.author_email)
189-
write_output("License: %s", dist.license)
193+
if metadata_version_tuple >= (2, 4) and dist.license_expression:
194+
write_output("License-Expression: %s", dist.license_expression)
195+
else:
196+
write_output("License: %s", dist.license)
190197
write_output("Location: %s", dist.location)
191198
if dist.editable_project_location is not None:
192199
write_output(
Binary file not shown.
Binary file not shown.

tests/functional/test_show.py

+42-1
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,21 @@ def test_all_fields(script: PipTestEnvironment) -> None:
217217
"""
218218
Test that all the fields are present
219219
"""
220+
# future-compat: once pip adopts PEP 639 in pyproject.toml and
221+
# its build backend produces metadata 2.4 or greater,
222+
# it will display "License-Expression" rather than License
223+
verbose = script.pip("show", "--verbose", "pip").stdout
224+
match = re.search(r"Metadata-Version:\s(\d+\.\d+)", verbose)
225+
if match is not None:
226+
metadata_version = match.group(1)
227+
metadata_version_tuple = tuple(map(int, metadata_version.split(".")))
228+
if metadata_version_tuple >= (2, 4) and "License-Expression" in verbose:
229+
license_str = "License-Expression"
230+
else:
231+
license_str = "License"
232+
else:
233+
license_str = "License"
234+
220235
result = script.pip("show", "pip")
221236
lines = result.stdout.splitlines()
222237
expected = {
@@ -226,7 +241,7 @@ def test_all_fields(script: PipTestEnvironment) -> None:
226241
"Home-page",
227242
"Author",
228243
"Author-email",
229-
"License",
244+
f"{license_str}",
230245
"Location",
231246
"Editable project location",
232247
"Requires",
@@ -410,3 +425,29 @@ def test_show_populate_homepage_from_project_urls(
410425
result = script.pip("show", "simple", cwd=pkg_path)
411426
lines = result.stdout.splitlines()
412427
assert "Home-page: https://example.com" in lines
428+
429+
430+
def test_show_license_expression(script: PipTestEnvironment, data: TestData) -> None:
431+
"""
432+
Show License-Expression if present in metadata >= 2.4.
433+
"""
434+
wheel_file = data.packages.joinpath("license.dist-0.1-py2.py3-none-any.whl")
435+
script.pip("install", "--no-index", wheel_file)
436+
result = script.pip("show", "license.dist")
437+
lines = result.stdout.splitlines()
438+
assert "License-Expression: MIT AND MIT-0" in lines
439+
assert "License: The legacy license declaration" not in lines
440+
441+
442+
def test_show_license_for_metadata_24(
443+
script: PipTestEnvironment, data: TestData
444+
) -> None:
445+
"""
446+
Show License if License-Expression is not there for metadata >= 2.4.
447+
"""
448+
wheel_file = data.packages.joinpath("license.dist-0.2-py2.py3-none-any.whl")
449+
script.pip("install", "--no-index", wheel_file)
450+
result = script.pip("show", "license.dist")
451+
lines = result.stdout.splitlines()
452+
assert "License-Expression: " not in lines
453+
assert "License: The legacy license declaration" in lines

0 commit comments

Comments
 (0)