diff --git a/news/13112.feature.rst b/news/13112.feature.rst new file mode 100644 index 00000000000..bf60883211f --- /dev/null +++ b/news/13112.feature.rst @@ -0,0 +1 @@ +Prefer to display ``License-Expression`` in ``pip show`` if metadata version is at least 2.4. diff --git a/src/pip/_internal/commands/show.py b/src/pip/_internal/commands/show.py index c54d548f5fb..b47500cf8b4 100644 --- a/src/pip/_internal/commands/show.py +++ b/src/pip/_internal/commands/show.py @@ -66,6 +66,7 @@ class _PackageInfo(NamedTuple): author: str author_email: str license: str + license_expression: str entry_points: List[str] files: Optional[List[str]] @@ -161,6 +162,7 @@ def _get_requiring_packages(current_dist: BaseDistribution) -> Iterator[str]: author=metadata.get("Author", ""), author_email=metadata.get("Author-email", ""), license=metadata.get("License", ""), + license_expression=metadata.get("License-Expression", ""), entry_points=entry_points, files=files, ) @@ -180,13 +182,18 @@ def print_results( if i > 0: write_output("---") + metadata_version_tuple = tuple(map(int, dist.metadata_version.split("."))) + write_output("Name: %s", dist.name) write_output("Version: %s", dist.version) write_output("Summary: %s", dist.summary) write_output("Home-page: %s", dist.homepage) write_output("Author: %s", dist.author) write_output("Author-email: %s", dist.author_email) - write_output("License: %s", dist.license) + if metadata_version_tuple >= (2, 4) and dist.license_expression: + write_output("License-Expression: %s", dist.license_expression) + else: + write_output("License: %s", dist.license) write_output("Location: %s", dist.location) if dist.editable_project_location is not None: write_output( diff --git a/tests/data/packages/license.dist-0.1-py2.py3-none-any.whl b/tests/data/packages/license.dist-0.1-py2.py3-none-any.whl new file mode 100644 index 00000000000..b1a73258dd1 Binary files /dev/null and b/tests/data/packages/license.dist-0.1-py2.py3-none-any.whl differ diff --git a/tests/data/packages/license.dist-0.2-py2.py3-none-any.whl b/tests/data/packages/license.dist-0.2-py2.py3-none-any.whl new file mode 100644 index 00000000000..db5662bdc1e Binary files /dev/null and b/tests/data/packages/license.dist-0.2-py2.py3-none-any.whl differ diff --git a/tests/functional/test_show.py b/tests/functional/test_show.py index 4cc1587733f..b7caea46ff8 100644 --- a/tests/functional/test_show.py +++ b/tests/functional/test_show.py @@ -217,6 +217,21 @@ def test_all_fields(script: PipTestEnvironment) -> None: """ Test that all the fields are present """ + # future-compat: once pip adopts PEP 639 in pyproject.toml and + # its build backend produces metadata 2.4 or greater, + # it will display "License-Expression" rather than License + verbose = script.pip("show", "--verbose", "pip").stdout + match = re.search(r"Metadata-Version:\s(\d+\.\d+)", verbose) + if match is not None: + metadata_version = match.group(1) + metadata_version_tuple = tuple(map(int, metadata_version.split("."))) + if metadata_version_tuple >= (2, 4) and "License-Expression" in verbose: + license_str = "License-Expression" + else: + license_str = "License" + else: + license_str = "License" + result = script.pip("show", "pip") lines = result.stdout.splitlines() expected = { @@ -226,7 +241,7 @@ def test_all_fields(script: PipTestEnvironment) -> None: "Home-page", "Author", "Author-email", - "License", + f"{license_str}", "Location", "Editable project location", "Requires", @@ -410,3 +425,29 @@ def test_show_populate_homepage_from_project_urls( result = script.pip("show", "simple", cwd=pkg_path) lines = result.stdout.splitlines() assert "Home-page: https://example.com" in lines + + +def test_show_license_expression(script: PipTestEnvironment, data: TestData) -> None: + """ + Show License-Expression if present in metadata >= 2.4. + """ + wheel_file = data.packages.joinpath("license.dist-0.1-py2.py3-none-any.whl") + script.pip("install", "--no-index", wheel_file) + result = script.pip("show", "license.dist") + lines = result.stdout.splitlines() + assert "License-Expression: MIT AND MIT-0" in lines + assert "License: The legacy license declaration" not in lines + + +def test_show_license_for_metadata_24( + script: PipTestEnvironment, data: TestData +) -> None: + """ + Show License if License-Expression is not there for metadata >= 2.4. + """ + wheel_file = data.packages.joinpath("license.dist-0.2-py2.py3-none-any.whl") + script.pip("install", "--no-index", wheel_file) + result = script.pip("show", "license.dist") + lines = result.stdout.splitlines() + assert "License-Expression: " not in lines + assert "License: The legacy license declaration" in lines