diff --git a/src/poetry/installation/chooser.py b/src/poetry/installation/chooser.py index 600a46306ce..53e746fdfd2 100644 --- a/src/poetry/installation/chooser.py +++ b/src/poetry/installation/chooser.py @@ -198,8 +198,7 @@ def _sort_key( has_allowed_hash = int(self._is_link_hash_allowed_for_package(link, package)) - # TODO: Proper yank value - yank_value = 0 + yank_value = int(not link.yanked) return ( has_allowed_hash, diff --git a/tests/installation/test_chooser.py b/tests/installation/test_chooser.py index 51c8b66c2ab..b4a8d36bc26 100644 --- a/tests/installation/test_chooser.py +++ b/tests/installation/test_chooser.py @@ -90,6 +90,26 @@ def callback( ) +@pytest.fixture() +def mock_legacy_partial_yank(http: type[httpretty.httpretty]) -> None: + def callback( + request: HTTPrettyRequest, uri: str, headers: dict[str, Any] + ) -> list[int | dict[str, Any] | str]: + parts = uri.rsplit("/") + name = parts[-2] + + fixture = LEGACY_FIXTURES / (name + "_partial_yank" + ".html") + + with fixture.open(encoding="utf-8") as f: + return [200, headers, f.read()] + + http.register_uri( + http.GET, + re.compile("^https://foo2.bar/simple/(.+?)$"), + body=callback, + ) + + @pytest.fixture() def pool() -> Pool: pool = Pool() @@ -98,6 +118,9 @@ def pool() -> Pool: pool.add_repository( LegacyRepository("foo", "https://foo.bar/simple/", disable_cache=True) ) + pool.add_repository( + LegacyRepository("foo2", "https://foo2.bar/simple/", disable_cache=True) + ) return pool @@ -266,6 +289,83 @@ def test_chooser_chooses_distributions_that_match_the_package_hashes( assert link.filename == "isort-4.3.4.tar.gz" +@pytest.mark.parametrize("source_type", ["", "legacy"]) +def test_chooser_chooses_yanked_if_no_others( + env: MockEnv, + mock_pypi: None, + mock_legacy: None, + source_type: str, + pool: Pool, +) -> None: + chooser = Chooser(pool, env) + + package = Package("black", "21.11b0") + files = [ + { + "filename": "black-21.11b0-py3-none-any.whl", + "hash": "sha256:0b1f66cbfadcd332ceeaeecf6373d9991d451868d2e2219ad0ac1213fb701117", # noqa: E501 + } + ] + if source_type == "legacy": + package = Package( + package.name, + package.version.text, + source_type="legacy", + source_reference="foo", + source_url="https://foo.bar/simple/", + ) + + package.files = files + + link = chooser.choose_for(package) + + assert link.filename == "black-21.11b0-py3-none-any.whl" + assert link.yanked + + +def test_chooser_does_not_choose_yanked_if_others( + mock_legacy: None, + mock_legacy_partial_yank: None, + pool: Pool, +) -> None: + chooser = Chooser(pool, MockEnv(supported_tags=[Tag("py2", "none", "any")])) + + package = Package("futures", "3.2.0") + files = [ + { + "filename": "futures-3.2.0-py2-none-any.whl", + "hash": "sha256:ec0a6cb848cc212002b9828c3e34c675e0c9ff6741dc445cab6fdd4e1085d1f1", # noqa: E501 + }, + { + "filename": "futures-3.2.0.tar.gz", + "hash": "sha256:9ec02aa7d674acb8618afb127e27fde7fc68994c0437ad759fa094a574adb265", # noqa: E501 + }, + ] + package = Package( + package.name, + package.version.text, + source_type="legacy", + source_reference="foo", + source_url="https://foo.bar/simple/", + ) + package_partial_yank = Package( + package.name, + package.version.text, + source_type="legacy", + source_reference="foo2", + source_url="https://foo2.bar/simple/", + ) + + package.files = files + package_partial_yank.files = files + + link = chooser.choose_for(package) + link_partial_yank = chooser.choose_for(package_partial_yank) + + assert link.filename == "futures-3.2.0-py2-none-any.whl" + assert link_partial_yank.filename == "futures-3.2.0.tar.gz" + + @pytest.mark.parametrize("source_type", ["", "legacy"]) def test_chooser_throws_an_error_if_package_hashes_do_not_match( env: MockEnv,