From ca7bb6bb4834f26a3586521afa948efe4fa9f963 Mon Sep 17 00:00:00 2001 From: Charalampos Stratakis Date: Mon, 5 Sep 2022 16:01:11 +0200 Subject: [PATCH] Fix crash when an empty dist-info/egg-info is present Resolves: rhbz#2115001 --- bad-metadata-fix.patch | 92 ++++++++++++++++++++++++++++++++++++++++++ python-pip.spec | 11 ++++- 2 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 bad-metadata-fix.patch diff --git a/bad-metadata-fix.patch b/bad-metadata-fix.patch new file mode 100644 index 0000000..740dc71 --- /dev/null +++ b/bad-metadata-fix.patch @@ -0,0 +1,92 @@ +From 6817fbfb1fd389ad61009f0199db5670b146c8d3 Mon Sep 17 00:00:00 2001 +From: Tzu-ping Chung +Date: Sat, 6 Aug 2022 06:18:59 +0800 +Subject: [PATCH] Skip dist if metadata does not have a valid name + +--- + news/11352.bugfix.rst | 2 ++ + src/pip/_internal/metadata/importlib/_compat.py | 14 +++++++++++++- + src/pip/_internal/metadata/importlib/_envs.py | 14 +++++++++++--- + 3 files changed, 26 insertions(+), 4 deletions(-) + create mode 100644 news/11352.bugfix.rst + +diff --git a/news/11352.bugfix.rst b/news/11352.bugfix.rst +new file mode 100644 +index 00000000000..78016c912ef +--- /dev/null ++++ b/news/11352.bugfix.rst +@@ -0,0 +1,2 @@ ++Ignore distributions with invalid ``Name`` in metadata instead of crashing, when ++using the ``importlib.metadata`` backend. +diff --git a/src/pip/_internal/metadata/importlib/_compat.py b/src/pip/_internal/metadata/importlib/_compat.py +index e0879807ab9..593bff23ede 100644 +--- a/src/pip/_internal/metadata/importlib/_compat.py ++++ b/src/pip/_internal/metadata/importlib/_compat.py +@@ -2,6 +2,15 @@ + from typing import Any, Optional, Protocol, cast + + ++class BadMetadata(ValueError): ++ def __init__(self, dist: importlib.metadata.Distribution, *, reason: str) -> None: ++ self.dist = dist ++ self.reason = reason ++ ++ def __str__(self) -> str: ++ return f"Bad metadata in {self.dist} ({self.reason})" ++ ++ + class BasePath(Protocol): + """A protocol that various path objects conform. + +@@ -40,4 +49,7 @@ def get_dist_name(dist: importlib.metadata.Distribution) -> str: + The ``name`` attribute is only available in Python 3.10 or later. We are + targeting exactly that, but Mypy does not know this. + """ +- return cast(Any, dist).name ++ name = cast(Any, dist).name ++ if not isinstance(name, str): ++ raise BadMetadata(dist, reason="invalid metadata entry 'name'") ++ return name +diff --git a/src/pip/_internal/metadata/importlib/_envs.py b/src/pip/_internal/metadata/importlib/_envs.py +index d5fcfdbfef2..cbec59e2c6d 100644 +--- a/src/pip/_internal/metadata/importlib/_envs.py ++++ b/src/pip/_internal/metadata/importlib/_envs.py +@@ -1,5 +1,6 @@ + import functools + import importlib.metadata ++import logging + import os + import pathlib + import sys +@@ -14,9 +15,11 @@ + from pip._internal.utils.deprecation import deprecated + from pip._internal.utils.filetypes import WHEEL_EXTENSION + +-from ._compat import BasePath, get_dist_name, get_info_location ++from ._compat import BadMetadata, BasePath, get_dist_name, get_info_location + from ._dists import Distribution + ++logger = logging.getLogger(__name__) ++ + + def _looks_like_wheel(location: str) -> bool: + if not location.endswith(WHEEL_EXTENSION): +@@ -56,11 +59,16 @@ def _find_impl(self, location: str) -> Iterator[FoundResult]: + # To know exactly where we find a distribution, we have to feed in the + # paths one by one, instead of dumping the list to importlib.metadata. + for dist in importlib.metadata.distributions(path=[location]): +- normalized_name = canonicalize_name(get_dist_name(dist)) ++ info_location = get_info_location(dist) ++ try: ++ raw_name = get_dist_name(dist) ++ except BadMetadata as e: ++ logger.warning("Skipping %s due to %s", info_location, e.reason) ++ continue ++ normalized_name = canonicalize_name(raw_name) + if normalized_name in self._found_names: + continue + self._found_names.add(normalized_name) +- info_location = get_info_location(dist) + yield dist, info_location + + def find(self, location: str) -> Iterator[BaseDistribution]: diff --git a/python-pip.spec b/python-pip.spec index 760c297..5beca9a 100644 --- a/python-pip.spec +++ b/python-pip.spec @@ -21,7 +21,7 @@ Name: python-%{srcname} Version: %{base_version}%{?prerel:~%{prerel}} -Release: 1%{?dist} +Release: 2%{?dist} Summary: A tool for installing and managing Python packages # We bundle a lot of libraries with pip, which itself is under MIT license. @@ -89,6 +89,11 @@ Patch: nowarn-pip._internal.main.patch # Upstream issue: https://github.com/pypa/packaging/issues/368 Patch: no-version-warning.patch +# Ignore distributions with invalid name in metadata instead of crashing, when +# using the importlib.metadata backend. +# Resolved upstream: https://github.com/pypa/pip/pull/11353 +Patch: bad-metadata-fix.patch + # Downstream only patch # Users might have local installations of pip from using # `pip install --user --upgrade pip` on older/newer versions. @@ -403,6 +408,10 @@ pytest_k='not completion and %{python_wheel_dir}/%{python_wheel_name} %changelog +* Mon Sep 05 2022 Charalampos Stratakis - 22.2.2-2 +- Fix crash when an empty dist-info/egg-info is present +Resolves: rhbz#2115001 + * Wed Aug 03 2022 Charalampos Stratakis - 22.2.2-1 - Update to 22.2.2 Resolves: rhbz#2109468