Skip to content

Commit b458d3e

Browse files
sbidoulpradyunsg
authored andcommitted
Ignore all candidates of a version when one has invalid metadata
We do this to avoid needlessly building a sdist when we have determined that a wheel has invalid metadata.
1 parent 83e77bf commit b458d3e

File tree

3 files changed

+35
-7
lines changed

3 files changed

+35
-7
lines changed

src/pip/_internal/resolution/resolvelib/factory.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ def _make_base_candidate_from_link(
235235
name=name,
236236
version=version,
237237
)
238-
except (MetadataInconsistent, MetadataInvalid) as e:
238+
except MetadataInconsistent as e:
239239
logger.info(
240240
"Discarding [blue underline]%s[/]: [yellow]%s[reset]",
241241
link,

src/pip/_internal/resolution/resolvelib/found_candidates.py

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,18 @@
99
"""
1010

1111
import functools
12+
import logging
1213
from collections.abc import Sequence
1314
from typing import TYPE_CHECKING, Any, Callable, Iterator, Optional, Set, Tuple
1415

1516
from pip._vendor.packaging.version import _BaseVersion
1617

18+
from pip._internal.exceptions import MetadataInvalid
19+
1720
from .base import Candidate
1821

22+
logger = logging.getLogger(__name__)
23+
1924
IndexCandidateInfo = Tuple[_BaseVersion, Callable[[], Optional[Candidate]]]
2025

2126
if TYPE_CHECKING:
@@ -44,11 +49,25 @@ def _iter_built(infos: Iterator[IndexCandidateInfo]) -> Iterator[Candidate]:
4449
for version, func in infos:
4550
if version in versions_found:
4651
continue
47-
candidate = func()
48-
if candidate is None:
49-
continue
50-
yield candidate
51-
versions_found.add(version)
52+
try:
53+
candidate = func()
54+
except MetadataInvalid as e:
55+
logger.warning(
56+
"Ignoring version %s of %s since it has invalid metadata:\n"
57+
"%s\n"
58+
"Please use pip<24.1 if you need to use this version.",
59+
version,
60+
e.ireq.name,
61+
e,
62+
)
63+
# Mark version as found to avoid trying other candidates with the same
64+
# version, since they most likely have invalid metadata as well.
65+
versions_found.add(version)
66+
else:
67+
if candidate is None:
68+
continue
69+
yield candidate
70+
versions_found.add(version)
5271

5372

5473
def _iter_built_with_prepended(

tests/functional/test_invalid_versions_and_specifiers.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,17 @@ def test_install_from_index_with_invalid_specifier(
2626
"""
2727
index_url = data.index_url("require-invalid-version")
2828
result = script.pip(
29-
"install", "--dry-run", "--index-url", index_url, "require-invalid-version"
29+
"install",
30+
"--dry-run",
31+
"--index-url",
32+
index_url,
33+
"require-invalid-version",
34+
allow_stderr_warning=True,
3035
)
36+
assert (
37+
"WARNING: Ignoring version 1.0 of require-invalid-version "
38+
"since it has invalid metadata"
39+
) in result.stderr
3140
assert "Would install require-invalid-version-0.1" in result.stdout
3241

3342

0 commit comments

Comments
 (0)