File tree Expand file tree Collapse file tree
src/pip/_internal/resolution/resolvelib
data/indexes/yanked_all/simple Expand file tree Collapse file tree Original file line number Diff line number Diff line change 1+ Prevent pip from installing yanked releases unless
2+ explicitely pinned via the ``== `` or ``=== `` operators.
Original file line number Diff line number Diff line change @@ -273,14 +273,27 @@ def iter_index_candidate_infos() -> Iterator[IndexCandidateInfo]:
273273 )
274274 icans = list (result .iter_applicable ())
275275
276- # PEP 592: Yanked releases must be ignored unless only yanked
277- # releases can satisfy the version range. So if this is false,
278- # all yanked icans need to be skipped .
276+ # PEP 592: Yanked releases are ignored unless the specifier
277+ # explicitely pins a version (via '==' or '===') that can be
278+ # solely satisfied by a yanked release .
279279 all_yanked = all (ican .link .is_yanked for ican in icans )
280280
281+ def is_pinned (specifier : SpecifierSet ) -> bool :
282+ for sp in specifier :
283+ if sp .operator == "===" :
284+ return True
285+ if sp .operator != "==" :
286+ continue
287+ if sp .version .endswith (".*" ):
288+ continue
289+ return True
290+ return False
291+
292+ pinned = is_pinned (specifier )
293+
281294 # PackageFinder returns earlier versions first, so we reverse.
282295 for ican in reversed (icans ):
283- if not all_yanked and ican .link .is_yanked :
296+ if not ( all_yanked and pinned ) and ican .link .is_yanked :
284297 continue
285298 func = functools .partial (
286299 self ._make_candidate_from_link ,
Original file line number Diff line number Diff line change 1+ < html >
2+ < body >
3+ < a data-yanked ="test reason message " href ="../../../packages/simple-1.0.tar.gz "> simple-1.0.tar.gz</ a >
4+ < a data-yanked ="test reason message " href ="../../../packages/simple-2.0.tar.gz "> simple-2.0.tar.gz</ a >
5+ < a data-yanked ="test reason message " href ="../../../packages/simple-3.0.tar.gz "> simple-3.0.tar.gz</ a >
6+ </ body >
7+ </ html >
Original file line number Diff line number Diff line change @@ -2172,6 +2172,24 @@ def test_install_yanked_file_and_print_warning(
21722172 assert "Successfully installed simple-3.0\n " in result .stdout , str (result )
21732173
21742174
2175+ def test_error_all_yanked_files_and_no_pin (script , data ):
2176+ """
2177+ Test raising an error if there are only "yanked" files available and no pin
2178+ """
2179+ result = script .pip (
2180+ "install" ,
2181+ "simple" ,
2182+ "--index-url" ,
2183+ data .index_url ("yanked_all" ),
2184+ expect_error = True ,
2185+ )
2186+ # Make sure an error is raised
2187+ assert (
2188+ result .returncode == 1
2189+ and "ERROR: No matching distribution found for simple\n " in result .stderr
2190+ ), str (result )
2191+
2192+
21752193@pytest .mark .parametrize (
21762194 "install_args" ,
21772195 [
You can’t perform that action at this time.
0 commit comments