Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Handle broken metadata by discarding package, or give a useful error #2119

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 33 additions & 1 deletion piptools/resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@

import collections
import copy
import re
from abc import ABCMeta, abstractmethod
from functools import partial
from itertools import chain, count, groupby
from typing import Any, Container, DefaultDict, Iterable, Iterator

import click
from pip._internal.exceptions import DistributionNotFound
from pip._internal.exceptions import DistributionNotFound, MetadataGenerationFailed
from pip._internal.operations.build.build_tracker import (
get_build_tracker,
update_env_context_manager,
Expand Down Expand Up @@ -670,6 +671,37 @@ def _do_resolve(

return False

except MetadataGenerationFailed as err:
# Find (part of) broken package name in the error message
match = re.search(r'name\s*=\s*"(\w+)"', str(err.__cause__.context))
if match:
partial_name = match.group(1)
possible_constraints = [
c for c in self.constraints if partial_name in c.name
]
for constraint in possible_constraints:
# Remove existing constraint that *might* cause the error
log.warning(
f"Discarding {constraint} to proceed the resolution.\n"
"It looks like it has a release with broken metadata, causing this resolver to fail.\n"
"You may try to pin that package's version (probably to a recent one), "
"so the resolver doesn't consider the broken release."
)
self.constraints.remove(constraint)

# We remove only one constraint at a time.
# If there are multiple candidates, we'll find them in the next round.
return False

# We also get here if there was a match, but possible_constraints is an empty list.
log.error(
"A package release has broken metadata, but we can't tell which package it is.\n "
"Try reading the error message above to identify the package.\n"
"Next, you may try to pin that package's version (probably to a recent one), "
"so the resolver doesn't consider the broken release."
)
raise

return True

def _get_install_requirements(
Expand Down
Loading