Skip to content

Commit

Permalink
Diagnostic error on pip uninstall of invalid package
Browse files Browse the repository at this point in the history
  • Loading branch information
notatallshaw committed Sep 4, 2024
1 parent c33c188 commit 0a1b222
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 2 deletions.
20 changes: 20 additions & 0 deletions src/pip/_internal/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@
if TYPE_CHECKING:
from hashlib import _Hash

from pip._vendor.packaging.requirements import InvalidRequirement
from pip._vendor.requests.models import Request, Response

from pip._internal.metadata import BaseDistribution
from pip._internal.req.req_install import InstallRequirement
from pip._internal.resolution.resolvelib.candidates import AlreadyInstalledCandidate

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -775,3 +777,21 @@ def __init__(self, *, distribution: "BaseDistribution") -> None:
),
hint_stmt=None,
)

class InvalidInstalledPackage(DiagnosticPipError):
reference = "invalid-installed-package"

def __init__(
self,
*,
package: "AlreadyInstalledCandidate",
invalid_req_exc: "InvalidRequirement",
) -> None:
super().__init__(
message=Text(
f"Cannot uninstall {package} because it has an invalid requirement:\n"
f"{invalid_req_exc.args[0]}."
),
context="Since pip 24.1+ invalid requirements can not be read by pip.",
hint_stmt="Please use 'pip<24.1' if you need to uninstall this package.",
)
9 changes: 7 additions & 2 deletions src/pip/_internal/resolution/resolvelib/candidates.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from pip._internal.exceptions import (
HashError,
InstallationSubprocessError,
InvalidInstalledPackage,
MetadataInconsistent,
MetadataInvalid,
)
Expand Down Expand Up @@ -398,8 +399,12 @@ def format_for_error(self) -> str:
def iter_dependencies(self, with_requires: bool) -> Iterable[Optional[Requirement]]:
if not with_requires:
return
for r in self.dist.iter_dependencies():
yield from self._factory.make_requirements_from_spec(str(r), self._ireq)

try:
for r in self.dist.iter_dependencies():
yield from self._factory.make_requirements_from_spec(str(r), self._ireq)
except InvalidRequirement as exc:
raise InvalidInstalledPackage(package=self, invalid_req_exc=exc) from None

def get_install_requirement(self) -> Optional[InstallRequirement]:
return None
Expand Down

0 comments on commit 0a1b222

Please sign in to comment.