diff --git a/pyproject.toml b/pyproject.toml
index 72c31dfbea7..1d3d70c1a65 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -94,7 +94,10 @@ build-backend = "poetry.core.masonry.api"
extend-exclude = [
"docs/*",
# External to the project's coding standards
- "tests/**/fixtures/*",
+ "tests/fixtures/git/*",
+ "tests/fixtures/project_with_setup*/*",
+ "tests/masonry/builders/fixtures/pep_561_stub_only*/*",
+ "tests/utils/fixtures/setups/*",
]
fix = true
line-length = 88
diff --git a/src/poetry/repositories/legacy_repository.py b/src/poetry/repositories/legacy_repository.py
index a6557eeb7d8..a6edf66729c 100644
--- a/src/poetry/repositories/legacy_repository.py
+++ b/src/poetry/repositories/legacy_repository.py
@@ -1,5 +1,7 @@
from __future__ import annotations
+from contextlib import suppress
+from functools import cached_property
from typing import TYPE_CHECKING
from typing import Any
@@ -11,6 +13,7 @@
from poetry.repositories.exceptions import PackageNotFound
from poetry.repositories.http_repository import HTTPRepository
from poetry.repositories.link_sources.html import SimpleRepositoryPage
+from poetry.repositories.link_sources.html import SimpleRepositoryRootPage
if TYPE_CHECKING:
@@ -36,18 +39,6 @@ def __init__(
super().__init__(name, url.rstrip("/"), config, disable_cache, pool_size)
- @property
- def packages(self) -> list[Package]:
- # LegacyRepository._packages is not populated and other implementations
- # implicitly rely on this (e.g. Pool.search via
- # LegacyRepository.search). To avoid special-casing Pool or changing
- # behavior, we stub and return an empty list.
- #
- # TODO: Rethinking search behaviour and design.
- # Ref: https://github.com/python-poetry/poetry/issues/2446 and
- # https://github.com/python-poetry/poetry/pull/6669#discussion_r990874908.
- return []
-
def package(
self, name: str, version: Version, extras: list[str] | None = None
) -> Package:
@@ -135,7 +126,29 @@ def _get_release_info(
)
def _get_page(self, name: NormalizedName) -> SimpleRepositoryPage:
- response = self._get_response(f"/{name}/")
- if not response:
+ if not (response := self._get_response(f"/{name}/")):
raise PackageNotFound(f"Package [{name}] not found.")
return SimpleRepositoryPage(response.url, response.text)
+
+ @cached_property
+ def root_page(self) -> SimpleRepositoryRootPage:
+ if not (response := self._get_response("/")):
+ self._log(
+ f"Unable to retrieve package listing from package source {self.name}",
+ level="error",
+ )
+ return SimpleRepositoryRootPage()
+
+ return SimpleRepositoryRootPage(response.text)
+
+ def search(self, query: str) -> list[Package]:
+ results: list[Package] = []
+
+ for candidate in self.root_page.search(query):
+ with suppress(PackageNotFound):
+ page = self.get_page(candidate)
+
+ for package in page.packages:
+ results.append(package)
+
+ return results
diff --git a/src/poetry/repositories/link_sources/html.py b/src/poetry/repositories/link_sources/html.py
index 7dfbd19e061..3128b15fa1b 100644
--- a/src/poetry/repositories/link_sources/html.py
+++ b/src/poetry/repositories/link_sources/html.py
@@ -68,6 +68,40 @@ def _link_cache(self) -> LinkCache:
return links
+class SimpleRepositoryRootPage:
+ """
+ This class represents the parsed content of a "simple" repository's root page. This follows the
+ specification laid out in PEP 503.
+
+ See: https://peps.python.org/pep-0503/
+ """
+
+ def __init__(self, content: str | None = None) -> None:
+ parser = HTMLPageParser()
+ parser.feed(content or "")
+ self._parsed = parser.anchors
+
+ def search(self, query: str) -> list[str]:
+ results: list[str] = []
+
+ for anchor in self._parsed:
+ href = anchor.get("href")
+ if href and query in href:
+ results.append(href.rstrip("/"))
+
+ return results
+
+ @cached_property
+ def package_names(self) -> list[str]:
+ results: list[str] = []
+
+ for anchor in self._parsed:
+ if href := anchor.get("href"):
+ results.append(href.rstrip("/"))
+
+ return results
+
+
class SimpleRepositoryPage(HTMLPage):
def __init__(self, url: str, content: str) -> None:
if not url.endswith("/"):
diff --git a/tests/conftest.py b/tests/conftest.py
index 70ff1545cf8..119f38cfe5b 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -11,6 +11,7 @@
from pathlib import Path
from typing import TYPE_CHECKING
from typing import Any
+from typing import Iterator
import httpretty
import keyring
@@ -62,6 +63,11 @@
from tests.types import SetProjectContext
+pytest_plugins = [
+ "tests.repositories.fixtures",
+]
+
+
def pytest_addoption(parser: Parser) -> None:
parser.addoption(
"--integration",
@@ -279,7 +285,6 @@ def download_mock(mocker: MockerFixture) -> None:
# Patch download to not download anything but to just copy from fixtures
mocker.patch("poetry.utils.helpers.download_file", new=mock_download)
mocker.patch("poetry.packages.direct_origin.download_file", new=mock_download)
- mocker.patch("poetry.repositories.http_repository.download_file", new=mock_download)
@pytest.fixture(autouse=True)
@@ -323,7 +328,7 @@ def git_mock(mocker: MockerFixture) -> None:
@pytest.fixture
def http() -> Iterator[type[httpretty.httpretty]]:
httpretty.reset()
- with httpretty.enabled(allow_net_connect=False):
+ with httpretty.enabled(allow_net_connect=False, verbose=True):
yield httpretty
@@ -532,6 +537,12 @@ def httpretty_windows_mock_urllib3_wait_for_socket(mocker: MockerFixture) -> Non
mocker.patch("urllib3.util.wait.select_wait_for_socket", returns=True)
+@pytest.fixture
+def disable_http_status_force_list(mocker: MockerFixture) -> Iterator[None]:
+ mocker.patch("poetry.utils.authenticator.STATUS_FORCELIST", [])
+ yield
+
+
@pytest.fixture(autouse=True)
def tmp_working_directory(tmp_path: Path) -> Iterator[Path]:
with switch_working_directory(tmp_path):
diff --git a/tests/console/commands/test_search.py b/tests/console/commands/test_search.py
index 9255fa2f4eb..f13c4193266 100644
--- a/tests/console/commands/test_search.py
+++ b/tests/console/commands/test_search.py
@@ -19,12 +19,6 @@
)
-@pytest.fixture(autouse=True)
-def mock_search_http_response(http: type[httpretty.httpretty]) -> None:
- with FIXTURES_DIRECTORY.joinpath("search.html").open(encoding="utf-8") as f:
- http.register_uri("GET", "https://pypi.org/search", f.read())
-
-
@pytest.fixture
def tester(command_tester_factory: CommandTesterFactory) -> CommandTester:
return command_tester_factory("search")
diff --git a/tests/helpers.py b/tests/helpers.py
index faf030e45d5..a1a63520b6f 100644
--- a/tests/helpers.py
+++ b/tests/helpers.py
@@ -43,6 +43,11 @@
from tests.types import HTTPrettyResponse
FIXTURE_PATH = Path(__file__).parent / "fixtures"
+FIXTURE_PATH_INSTALLATION = Path(__file__).parent / "installation" / "fixtures"
+FIXTURE_PATH_DISTRIBUTIONS = FIXTURE_PATH / "distributions"
+FIXTURE_PATH_REPOSITORIES = Path(__file__).parent / "repositories" / "fixtures"
+FIXTURE_PATH_REPOSITORIES_LEGACY = FIXTURE_PATH_REPOSITORIES / "legacy"
+FIXTURE_PATH_REPOSITORIES_PYPI = FIXTURE_PATH_REPOSITORIES / "pypi.org"
# Used as a mock for latest git revision.
MOCK_DEFAULT_GIT_REVISION = "9cf87a285a2d3fbb0b9fa621997b3acc3631ed24"
diff --git a/tests/inspection/test_lazy_wheel.py b/tests/inspection/test_lazy_wheel.py
index db149fb31c4..1a71cf0b441 100644
--- a/tests/inspection/test_lazy_wheel.py
+++ b/tests/inspection/test_lazy_wheel.py
@@ -32,6 +32,7 @@
from tests.types import HTTPPrettyRequestCallbackWrapper
from tests.types import HTTPrettyRequestCallback
from tests.types import HTTPrettyResponse
+ from tests.types import PackageDistributionLookup
class RequestCallbackFactory(Protocol):
def __call__(
@@ -110,7 +111,10 @@ def build_partial_response(
@pytest.fixture
-def handle_request_factory(fixture_dir: FixtureDirGetter) -> RequestCallbackFactory:
+def handle_request_factory(
+ fixture_dir: FixtureDirGetter,
+ package_distribution_lookup: PackageDistributionLookup,
+) -> RequestCallbackFactory:
def _factory(
*,
accept_ranges: str | None = "bytes",
@@ -122,17 +126,12 @@ def handle_request(
) -> HTTPrettyResponse:
name = Path(urlparse(uri).path).name
- wheel = Path(__file__).parents[1] / (
- "repositories/fixtures/pypi.org/dists/" + name
+ wheel = package_distribution_lookup(name) or package_distribution_lookup(
+ "demo-0.1.0-py2.py3-none-any.whl"
)
- if not wheel.exists():
- wheel = fixture_dir("distributions") / name
-
- if not wheel.exists():
- wheel = (
- fixture_dir("distributions") / "demo-0.1.0-py2.py3-none-any.whl"
- )
+ if not wheel:
+ return 404, response_headers, b"Not Found"
wheel_bytes = wheel.read_bytes()
diff --git a/tests/installation/conftest.py b/tests/installation/conftest.py
index c19a17f6f88..e69de29bb2d 100644
--- a/tests/installation/conftest.py
+++ b/tests/installation/conftest.py
@@ -1,45 +0,0 @@
-from __future__ import annotations
-
-import re
-
-from pathlib import Path
-from typing import TYPE_CHECKING
-from typing import Any
-from urllib.parse import urlparse
-
-import pytest
-
-
-if TYPE_CHECKING:
- from httpretty import httpretty
- from httpretty.core import HTTPrettyRequest
-
- from tests.types import FixtureDirGetter
-
-
-@pytest.fixture
-def mock_file_downloads(http: type[httpretty], fixture_dir: FixtureDirGetter) -> None:
- def callback(
- request: HTTPrettyRequest, uri: str, headers: dict[str, Any]
- ) -> list[int | dict[str, Any] | bytes]:
- name = Path(urlparse(uri).path).name
-
- fixture = Path(__file__).parent.parent.joinpath(
- "repositories/fixtures/pypi.org/dists/" + name
- )
-
- if not fixture.exists():
- fixture = fixture_dir("distributions") / name
-
- if not fixture.exists():
- fixture = (
- fixture_dir("distributions") / "demo-0.1.0-py2.py3-none-any.whl"
- )
-
- return [200, headers, fixture.read_bytes()]
-
- http.register_uri(
- http.GET,
- re.compile("^https://files.pythonhosted.org/.*$"),
- body=callback,
- )
diff --git a/tests/installation/fixtures/old-lock.test b/tests/installation/fixtures/old-lock.test
index 2e058c7f01d..c6b13e72f81 100644
--- a/tests/installation/fixtures/old-lock.test
+++ b/tests/installation/fixtures/old-lock.test
@@ -79,34 +79,34 @@ content-hash = "123456789"
[metadata.files]
attrs = [
- {file = "attrs-17.4.0-py2.py3-none-any.whl", hash = "sha256:a17a9573a6f475c99b551c0e0a812707ddda1ec9653bed04c13841404ed6f450"},
- {file = "attrs-17.4.0.tar.gz", hash = "sha256:1c7960ccfd6a005cd9f7ba884e6316b5e430a3f1a6c37c5f87d8b43f83b54ec9"},
+ {file = "attrs-17.4.0-py2.py3-none-any.whl", hash = "sha256:d38e57f381e891928357c68e300d28d3d4dcddc50486d5f8dfaf743d40477619"},
+ {file = "attrs-17.4.0.tar.gz", hash = "sha256:eb7536a1e6928190b3008c5b350bdf9850d619fff212341cd096f87a27a5e564"},
]
colorama = [
- {file = "colorama-0.3.9-py2.py3-none-any.whl", hash = "sha256:463f8483208e921368c9f306094eb6f725c6ca42b0f97e313cb5d5512459feda"},
- {file = "colorama-0.3.9.tar.gz", hash = "sha256:48eb22f4f8461b1df5734a074b57042430fb06e1d61bd1e11b078c0fe6d7a1f1"},
+ {file = "colorama-0.3.9-py2.py3-none-any.whl", hash = "sha256:5b632359f1ed2b7676a869812ba0edaacb99be04679b29eb56c07a5e137ab5a2"},
+ {file = "colorama-0.3.9.tar.gz", hash = "sha256:4c5a15209723ce1330a5c193465fe221098f761e9640d823a2ce7c03f983137f"},
]
funcsigs = [
- {file = "funcsigs-1.0.2-py2.py3-none-any.whl", hash = "sha256:330cc27ccbf7f1e992e69fef78261dc7c6569012cf397db8d3de0234e6c937ca"},
- {file = "funcsigs-1.0.2.tar.gz", hash = "sha256:a7bb0f2cf3a3fd1ab2732cb49eba4252c2af4240442415b4abce3b87022a8f50"},
+ {file = "funcsigs-1.0.2-py2.py3-none-any.whl", hash = "sha256:510ab97424949e726b4b44294018e90142c9aadf8e737cf3a125b4cffed42e79"},
+ {file = "funcsigs-1.0.2.tar.gz", hash = "sha256:c55716fcd1228645c214b44568d1fb9af2e28668a9c58e72a17a89a75d24ecd6"},
]
more-itertools = [
- {file = "more-itertools-4.1.0.tar.gz", hash = "sha256:c9ce7eccdcb901a2c75d326ea134e0886abfbea5f93e91cc95de9507c0816c44"},
- {file = "more_itertools-4.1.0-py2-none-any.whl", hash = "sha256:11a625025954c20145b37ff6309cd54e39ca94f72f6bb9576d1195db6fa2442e"},
- {file = "more_itertools-4.1.0-py3-none-any.whl", hash = "sha256:0dd8f72eeab0d2c3bd489025bb2f6a1b8342f9b198f6fc37b52d15cfa4531fea"},
+ {file = "more-itertools-4.1.0.tar.gz", hash = "sha256:bab2dc6f4be8f9a4a72177842c5283e2dff57c167439a03e3d8d901e854f0f2e"},
+ {file = "more_itertools-4.1.0-py2-none-any.whl", hash = "sha256:5dd7dfd88d2fdaea446da478ffef8d7151fdf26ee92ac7ed7b14e8d71efe4b62"},
+ {file = "more_itertools-4.1.0-py3-none-any.whl", hash = "sha256:29b1e1661aaa56875ce090fa219fa84dfc13daecb52cd4fae321f6f57b419ec4"},
]
pluggy = [
- {file = "pluggy-0.6.0.tar.gz", hash = "sha256:7f8ae7f5bdf75671a718d2daf0a64b7885f74510bcd98b1a0bb420eb9a9d0cff"},
+ {file = "pluggy-0.6.0.tar.gz", hash = "sha256:a982e208d054867661d27c6d2a86b17ba05fbb6b1bdc01f42660732dd107f865"},
]
py = [
- {file = "py-1.5.3-py2.py3-none-any.whl", hash = "sha256:983f77f3331356039fdd792e9220b7b8ee1aa6bd2b25f567a963ff1de5a64f6a"},
- {file = "py-1.5.3.tar.gz", hash = "sha256:29c9fab495d7528e80ba1e343b958684f4ace687327e6f789a94bf3d1915f881"},
+ {file = "py-1.5.3-py2.py3-none-any.whl", hash = "sha256:43ee6c7f95e0ec6a906de49906b79d138d89728fff17109d49f086abc2fdd985"},
+ {file = "py-1.5.3.tar.gz", hash = "sha256:2df2c513c3af11de15f58189ba5539ddc4768c6f33816dc5c03950c8bd6180fa"},
]
pytest = [
- {file = "pytest-3.5.0-py2.py3-none-any.whl", hash = "sha256:6266f87ab64692112e5477eba395cfedda53b1933ccd29478e671e73b420c19c"},
- {file = "pytest-3.5.0.tar.gz", hash = "sha256:fae491d1874f199537fd5872b5e1f0e74a009b979df9d53d1553fd03da1703e1"},
+ {file = "pytest-3.5.0-py2.py3-none-any.whl", hash = "sha256:28e4d9c2ae3196d74805c2eba24f350ae4c791a5b9b397c79b41506a48dc64ca"},
+ {file = "pytest-3.5.0.tar.gz", hash = "sha256:677b1d6decd29c041fe64276f29f79fbe66e40c59e445eb251366b4a8ab8bf68"},
]
six = [
- {file = "six-1.11.0-py2.py3-none-any.whl", hash = "sha256:832dc0e10feb1aa2c68dcc57dbb658f1c7e65b9b61af69048abc87a2db00a0eb"},
- {file = "six-1.11.0.tar.gz", hash = "sha256:70e8a77beed4562e7f14fe23a786b54f6296e34344c23bc42f07b15018ff98e9"},
+ {file = "six-1.11.0-py2.py3-none-any.whl", hash = "sha256:112f5b46e6aa106db3e4e2494a03694c938f41c4c4535edbdfc816c2e0cb50f2"},
+ {file = "six-1.11.0.tar.gz", hash = "sha256:268a4ccb159c1a2d2c79336b02e75058387b0cdbb4cea2f07846a758f48a356d"},
]
diff --git a/tests/installation/fixtures/with-pypi-repository.test b/tests/installation/fixtures/with-pypi-repository.test
index 3ada7ffc673..2309188b551 100644
--- a/tests/installation/fixtures/with-pypi-repository.test
+++ b/tests/installation/fixtures/with-pypi-repository.test
@@ -1,4 +1,4 @@
-# This file is automatically @generated by Poetry 1.5.0.dev0 and should not be changed by hand.
+# This file is automatically @generated by Poetry 1.9.0.dev0 and should not be changed by hand.
[[package]]
name = "attrs"
@@ -7,8 +7,8 @@ description = "Classes Without Boilerplate"
optional = false
python-versions = "*"
files = [
- {file = "attrs-17.4.0-py2.py3-none-any.whl", hash = "sha256:a17a9573a6f475c99b551c0e0a812707ddda1ec9653bed04c13841404ed6f450"},
- {file = "attrs-17.4.0.tar.gz", hash = "sha256:1c7960ccfd6a005cd9f7ba884e6316b5e430a3f1a6c37c5f87d8b43f83b54ec9"},
+ {file = "attrs-17.4.0-py2.py3-none-any.whl", hash = "sha256:d38e57f381e891928357c68e300d28d3d4dcddc50486d5f8dfaf743d40477619"},
+ {file = "attrs-17.4.0.tar.gz", hash = "sha256:eb7536a1e6928190b3008c5b350bdf9850d619fff212341cd096f87a27a5e564"},
]
[package.extras]
@@ -23,8 +23,8 @@ description = "Cross-platform colored terminal text."
optional = false
python-versions = "*"
files = [
- {file = "colorama-0.3.9-py2.py3-none-any.whl", hash = "sha256:463f8483208e921368c9f306094eb6f725c6ca42b0f97e313cb5d5512459feda"},
- {file = "colorama-0.3.9.tar.gz", hash = "sha256:48eb22f4f8461b1df5734a074b57042430fb06e1d61bd1e11b078c0fe6d7a1f1"},
+ {file = "colorama-0.3.9-py2.py3-none-any.whl", hash = "sha256:5b632359f1ed2b7676a869812ba0edaacb99be04679b29eb56c07a5e137ab5a2"},
+ {file = "colorama-0.3.9.tar.gz", hash = "sha256:4c5a15209723ce1330a5c193465fe221098f761e9640d823a2ce7c03f983137f"},
]
[[package]]
@@ -34,9 +34,9 @@ description = "More routines for operating on iterables, beyond itertools"
optional = false
python-versions = "*"
files = [
- {file = "more-itertools-4.1.0.tar.gz", hash = "sha256:c9ce7eccdcb901a2c75d326ea134e0886abfbea5f93e91cc95de9507c0816c44"},
- {file = "more_itertools-4.1.0-py2-none-any.whl", hash = "sha256:11a625025954c20145b37ff6309cd54e39ca94f72f6bb9576d1195db6fa2442e"},
- {file = "more_itertools-4.1.0-py3-none-any.whl", hash = "sha256:0dd8f72eeab0d2c3bd489025bb2f6a1b8342f9b198f6fc37b52d15cfa4531fea"},
+ {file = "more-itertools-4.1.0.tar.gz", hash = "sha256:bab2dc6f4be8f9a4a72177842c5283e2dff57c167439a03e3d8d901e854f0f2e"},
+ {file = "more_itertools-4.1.0-py2-none-any.whl", hash = "sha256:5dd7dfd88d2fdaea446da478ffef8d7151fdf26ee92ac7ed7b14e8d71efe4b62"},
+ {file = "more_itertools-4.1.0-py3-none-any.whl", hash = "sha256:29b1e1661aaa56875ce090fa219fa84dfc13daecb52cd4fae321f6f57b419ec4"},
]
[package.dependencies]
@@ -49,7 +49,7 @@ description = "plugin and hook calling mechanisms for python"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
files = [
- {file = "pluggy-0.6.0.tar.gz", hash = "sha256:7f8ae7f5bdf75671a718d2daf0a64b7885f74510bcd98b1a0bb420eb9a9d0cff"},
+ {file = "pluggy-0.6.0.tar.gz", hash = "sha256:a982e208d054867661d27c6d2a86b17ba05fbb6b1bdc01f42660732dd107f865"},
]
[[package]]
@@ -59,8 +59,8 @@ description = "library with cross-python path, ini-parsing, io, code, log facili
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
files = [
- {file = "py-1.5.3-py2.py3-none-any.whl", hash = "sha256:983f77f3331356039fdd792e9220b7b8ee1aa6bd2b25f567a963ff1de5a64f6a"},
- {file = "py-1.5.3.tar.gz", hash = "sha256:29c9fab495d7528e80ba1e343b958684f4ace687327e6f789a94bf3d1915f881"},
+ {file = "py-1.5.3-py2.py3-none-any.whl", hash = "sha256:43ee6c7f95e0ec6a906de49906b79d138d89728fff17109d49f086abc2fdd985"},
+ {file = "py-1.5.3.tar.gz", hash = "sha256:2df2c513c3af11de15f58189ba5539ddc4768c6f33816dc5c03950c8bd6180fa"},
]
[[package]]
@@ -70,8 +70,8 @@ description = "pytest: simple powerful testing with Python"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
files = [
- {file = "pytest-3.5.0-py2.py3-none-any.whl", hash = "sha256:6266f87ab64692112e5477eba395cfedda53b1933ccd29478e671e73b420c19c"},
- {file = "pytest-3.5.0.tar.gz", hash = "sha256:fae491d1874f199537fd5872b5e1f0e74a009b979df9d53d1553fd03da1703e1"},
+ {file = "pytest-3.5.0-py2.py3-none-any.whl", hash = "sha256:28e4d9c2ae3196d74805c2eba24f350ae4c791a5b9b397c79b41506a48dc64ca"},
+ {file = "pytest-3.5.0.tar.gz", hash = "sha256:677b1d6decd29c041fe64276f29f79fbe66e40c59e445eb251366b4a8ab8bf68"},
]
[package.dependencies]
@@ -91,7 +91,7 @@ optional = false
python-versions = ">=3.7"
files = [
{file = "setuptools-67.6.1-py3-none-any.whl", hash = "sha256:e728ca814a823bf7bf60162daf9db95b93d532948c4c0bea762ce62f60189078"},
- {file = "setuptools-67.6.1.tar.gz", hash = "sha256:257de92a9d50a60b8e22abfcbb771571fde0dbf3ec234463212027a4eeecbe9a"},
+ {file = "setuptools-67.6.1.tar.gz", hash = "sha256:a737d365c957dd3fced9ddd246118e95dce7a62c3dc49f37e7fdd9e93475d785"},
]
[package.extras]
@@ -106,8 +106,8 @@ description = "Python 2 and 3 compatibility utilities"
optional = false
python-versions = "*"
files = [
- {file = "six-1.11.0-py2.py3-none-any.whl", hash = "sha256:832dc0e10feb1aa2c68dcc57dbb658f1c7e65b9b61af69048abc87a2db00a0eb"},
- {file = "six-1.11.0.tar.gz", hash = "sha256:70e8a77beed4562e7f14fe23a786b54f6296e34344c23bc42f07b15018ff98e9"},
+ {file = "six-1.11.0-py2.py3-none-any.whl", hash = "sha256:112f5b46e6aa106db3e4e2494a03694c938f41c4c4535edbdfc816c2e0cb50f2"},
+ {file = "six-1.11.0.tar.gz", hash = "sha256:268a4ccb159c1a2d2c79336b02e75058387b0cdbb4cea2f07846a758f48a356d"},
]
[metadata]
diff --git a/tests/installation/test_chef.py b/tests/installation/test_chef.py
index 1df347982d6..2925d387935 100644
--- a/tests/installation/test_chef.py
+++ b/tests/installation/test_chef.py
@@ -23,7 +23,6 @@
from poetry.repositories import RepositoryPool
from poetry.utils.env import EnvManager
from poetry.utils.env import ephemeral_environment
-from tests.repositories.test_pypi_repository import MockRepository
if TYPE_CHECKING:
@@ -31,16 +30,17 @@
from pytest_mock import MockerFixture
+ from poetry.repositories.pypi_repository import PyPiRepository
from poetry.utils.cache import ArtifactCache
from tests.conftest import Config
from tests.types import FixtureDirGetter
@pytest.fixture()
-def pool() -> RepositoryPool:
+def pool(pypi_repository: PyPiRepository) -> RepositoryPool:
pool = RepositoryPool()
- pool.add_repository(MockRepository())
+ pool.add_repository(pypi_repository)
return pool
@@ -50,9 +50,7 @@ def setup(mocker: MockerFixture, pool: RepositoryPool) -> None:
mocker.patch.object(Factory, "create_pool", return_value=pool)
-def test_isolated_env_install_success(
- pool: RepositoryPool, mock_file_downloads: None
-) -> None:
+def test_isolated_env_install_success(pool: RepositoryPool) -> None:
with ephemeral_environment(Path(sys.executable)) as venv:
env = IsolatedEnv(venv, pool)
assert "poetry-core" not in venv.run("pip", "freeze")
@@ -92,7 +90,6 @@ def test_prepare_sdist(
config_cache_dir: Path,
artifact_cache: ArtifactCache,
fixture_dir: FixtureDirGetter,
- mock_file_downloads: None,
) -> None:
chef = Chef(
artifact_cache, EnvManager.get_system_env(), Factory.create_pool(config)
@@ -111,7 +108,6 @@ def test_prepare_directory(
config_cache_dir: Path,
artifact_cache: ArtifactCache,
fixture_dir: FixtureDirGetter,
- mock_file_downloads: None,
) -> None:
chef = Chef(
artifact_cache, EnvManager.get_system_env(), Factory.create_pool(config)
@@ -155,7 +151,6 @@ def test_prepare_directory_editable(
config_cache_dir: Path,
artifact_cache: ArtifactCache,
fixture_dir: FixtureDirGetter,
- mock_file_downloads: None,
) -> None:
chef = Chef(
artifact_cache, EnvManager.get_system_env(), Factory.create_pool(config)
diff --git a/tests/installation/test_chooser.py b/tests/installation/test_chooser.py
index f74400dc489..dd0aa7baa97 100644
--- a/tests/installation/test_chooser.py
+++ b/tests/installation/test_chooser.py
@@ -1,10 +1,7 @@
from __future__ import annotations
-import re
-
from pathlib import Path
from typing import TYPE_CHECKING
-from typing import Any
import pytest
@@ -19,12 +16,9 @@
if TYPE_CHECKING:
- import httpretty
-
- from httpretty.core import HTTPrettyRequest
-
from tests.conftest import Config
-
+ from tests.types import DistributionHashGetter
+ from tests.types import SpecializedLegacyRepositoryMocker
JSON_FIXTURES = (
Path(__file__).parent.parent / "repositories" / "fixtures" / "pypi.org" / "json"
@@ -44,84 +38,16 @@ def env() -> MockEnv:
@pytest.fixture()
-def mock_pypi(http: type[httpretty.httpretty]) -> None:
- def callback(
- request: HTTPrettyRequest, uri: str, headers: dict[str, Any]
- ) -> list[int | dict[str, Any] | str] | None:
- parts = uri.rsplit("/")
-
- name = parts[-3]
- version = parts[-2]
-
- fixture = JSON_FIXTURES / name / (version + ".json")
- if not fixture.exists():
- fixture = JSON_FIXTURES / (name + ".json")
-
- if not fixture.exists():
- return None
-
- with fixture.open(encoding="utf-8") as f:
- return [200, headers, f.read()]
-
- http.register_uri(
- http.GET,
- re.compile("^https://pypi.org/(.+?)/(.+?)/json$"),
- body=callback,
- )
-
-
-@pytest.fixture()
-def mock_legacy(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 + ".html")
-
- with fixture.open(encoding="utf-8") as f:
- return [200, headers, f.read()]
-
- http.register_uri(
- http.GET,
- re.compile("^https://foo.bar/simple/(.+?)$"),
- body=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() -> RepositoryPool:
+def pool(legacy_repository: LegacyRepository) -> RepositoryPool:
pool = RepositoryPool()
pool.add_repository(PyPiRepository(disable_cache=True))
pool.add_repository(
- LegacyRepository("foo", "https://foo.bar/simple/", disable_cache=True)
+ LegacyRepository("foo", "https://legacy.foo.bar/simple/", disable_cache=True)
)
pool.add_repository(
- LegacyRepository("foo2", "https://foo2.bar/simple/", disable_cache=True)
+ LegacyRepository("foo2", "https://legacy.foo2.bar/simple/", disable_cache=True)
)
-
return pool
@@ -143,7 +69,7 @@ def check_chosen_link_filename(
package.version.text,
source_type="legacy",
source_reference="foo",
- source_url="https://foo.bar/simple/",
+ source_url="https://legacy.foo.bar/simple/",
)
try:
@@ -163,8 +89,6 @@ def check_chosen_link_filename(
@pytest.mark.parametrize("source_type", ["", "legacy"])
def test_chooser_chooses_universal_wheel_link_if_available(
env: MockEnv,
- mock_pypi: None,
- mock_legacy: None,
source_type: str,
pool: RepositoryPool,
) -> None:
@@ -186,8 +110,6 @@ def test_chooser_chooses_universal_wheel_link_if_available(
@pytest.mark.parametrize("source_type", ["", "legacy"])
def test_chooser_no_binary_policy(
env: MockEnv,
- mock_pypi: None,
- mock_legacy: None,
source_type: str,
pool: RepositoryPool,
policy: str,
@@ -211,8 +133,6 @@ def test_chooser_no_binary_policy(
@pytest.mark.parametrize("source_type", ["", "legacy"])
def test_chooser_only_binary_policy(
env: MockEnv,
- mock_pypi: None,
- mock_legacy: None,
source_type: str,
pool: RepositoryPool,
policy: str,
@@ -240,8 +160,6 @@ def test_chooser_only_binary_policy(
@pytest.mark.parametrize("source_type", ["", "legacy"])
def test_chooser_multiple_binary_policy(
env: MockEnv,
- mock_pypi: None,
- mock_legacy: None,
source_type: str,
pool: RepositoryPool,
no_binary: str,
@@ -263,8 +181,6 @@ def test_chooser_multiple_binary_policy(
@pytest.mark.parametrize("source_type", ["", "legacy"])
def test_chooser_chooses_specific_python_universal_wheel_link_if_available(
env: MockEnv,
- mock_pypi: None,
- mock_legacy: None,
source_type: str,
pool: RepositoryPool,
) -> None:
@@ -275,7 +191,7 @@ def test_chooser_chooses_specific_python_universal_wheel_link_if_available(
@pytest.mark.parametrize("source_type", ["", "legacy"])
def test_chooser_chooses_system_specific_wheel_link_if_available(
- mock_pypi: None, mock_legacy: None, source_type: str, pool: RepositoryPool
+ source_type: str, pool: RepositoryPool
) -> None:
env = MockEnv(
supported_tags=[Tag("cp37", "cp37m", "win32"), Tag("py3", "none", "any")]
@@ -294,8 +210,6 @@ def test_chooser_chooses_system_specific_wheel_link_if_available(
@pytest.mark.parametrize("source_type", ["", "legacy"])
def test_chooser_chooses_sdist_if_no_compatible_wheel_link_is_available(
env: MockEnv,
- mock_pypi: None,
- mock_legacy: None,
source_type: str,
pool: RepositoryPool,
) -> None:
@@ -307,21 +221,21 @@ def test_chooser_chooses_sdist_if_no_compatible_wheel_link_is_available(
@pytest.mark.parametrize("source_type", ["", "legacy"])
def test_chooser_chooses_distributions_that_match_the_package_hashes(
env: MockEnv,
- mock_pypi: None,
- mock_legacy: None,
source_type: str,
pool: RepositoryPool,
+ dist_hash_getter: DistributionHashGetter,
) -> None:
chooser = Chooser(pool, env)
package = Package("isort", "4.3.4")
files = [
{
- "hash": (
- "sha256:b9c40e9750f3d77e6e4d441d8b0266cf555e7cdabdcff33c4fd06366ca761ef8"
- ),
- "filename": "isort-4.3.4.tar.gz",
+ "file": filename,
+ "hash": (f"sha256:{dist_hash_getter(filename).sha256}"),
}
+ for filename in [
+ f"{package.name}-{package.version}.tar.gz",
+ ]
]
if source_type == "legacy":
package = Package(
@@ -329,7 +243,7 @@ def test_chooser_chooses_distributions_that_match_the_package_hashes(
package.version.text,
source_type="legacy",
source_reference="foo",
- source_url="https://foo.bar/simple/",
+ source_url="https://legacy.foo.bar/simple/",
)
package.files = files
@@ -342,21 +256,19 @@ def test_chooser_chooses_distributions_that_match_the_package_hashes(
@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: RepositoryPool,
+ dist_hash_getter: DistributionHashGetter,
) -> None:
chooser = Chooser(pool, env)
package = Package("black", "21.11b0")
files = [
{
- "filename": "black-21.11b0-py3-none-any.whl",
- "hash": (
- "sha256:0b1f66cbfadcd332ceeaeecf6373d9991d451868d2e2219ad0ac1213fb701117"
- ),
+ "filename": filename,
+ "hash": (f"sha256:{dist_hash_getter(filename).sha256}"),
}
+ for filename in [f"{package.name}-{package.version}-py3-none-any.whl"]
]
if source_type == "legacy":
package = Package(
@@ -364,7 +276,7 @@ def test_chooser_chooses_yanked_if_no_others(
package.version.text,
source_type="legacy",
source_reference="foo",
- source_url="https://foo.bar/simple/",
+ source_url="https://legacy.foo.bar/simple/",
)
package.files = files
@@ -376,36 +288,44 @@ def test_chooser_chooses_yanked_if_no_others(
def test_chooser_does_not_choose_yanked_if_others(
- mock_legacy: None,
- mock_legacy_partial_yank: None,
+ specialized_legacy_repository_mocker: SpecializedLegacyRepositoryMocker,
pool: RepositoryPool,
+ dist_hash_getter: DistributionHashGetter,
) -> None:
chooser = Chooser(pool, MockEnv(supported_tags=[Tag("py2", "none", "any")]))
+ repo = pool.repository("foo2")
+ pool.remove_repository("foo2")
+
+ assert isinstance(repo, LegacyRepository)
+ pool.add_repository(
+ specialized_legacy_repository_mocker("-partial-yank", repo.name, repo.url)
+ )
+
package = Package("futures", "3.2.0")
files = [
{
- "filename": "futures-3.2.0-py2-none-any.whl",
- "hash": "sha256:ec0a6cb848cc212002b9828c3e34c675e0c9ff6741dc445cab6fdd4e1085d1f1",
- },
- {
- "filename": "futures-3.2.0.tar.gz",
- "hash": "sha256:9ec02aa7d674acb8618afb127e27fde7fc68994c0437ad759fa094a574adb265",
- },
+ "filename": filename,
+ "hash": (f"sha256:{dist_hash_getter(filename).sha256}"),
+ }
+ for filename in [
+ f"{package.name}-{package.version}-py2-none-any.whl",
+ f"{package.name}-{package.version}.tar.gz",
+ ]
]
package = Package(
package.name,
package.version.text,
source_type="legacy",
source_reference="foo",
- source_url="https://foo.bar/simple/",
+ source_url="https://legacy.foo.bar/simple/",
)
package_partial_yank = Package(
package.name,
package.version.text,
source_type="legacy",
source_reference="foo2",
- source_url="https://foo2.bar/simple/",
+ source_url="https://legacy.foo2.bar/simple/",
)
package.files = files
@@ -421,8 +341,6 @@ def test_chooser_does_not_choose_yanked_if_others(
@pytest.mark.parametrize("source_type", ["", "legacy"])
def test_chooser_throws_an_error_if_package_hashes_do_not_match(
env: MockEnv,
- mock_pypi: None,
- mock_legacy: None,
source_type: None,
pool: RepositoryPool,
) -> None:
@@ -443,7 +361,7 @@ def test_chooser_throws_an_error_if_package_hashes_do_not_match(
package.version.text,
source_type="legacy",
source_reference="foo",
- source_url="https://foo.bar/simple/",
+ source_url="https://legacy.foo.bar/simple/",
)
package.files = files
@@ -453,9 +371,8 @@ def test_chooser_throws_an_error_if_package_hashes_do_not_match(
assert files[0]["hash"] in str(e)
-@pytest.mark.usefixtures("mock_legacy")
def test_chooser_md5_remote_fallback_to_sha256_inline_calculation(
- env: MockEnv, pool: RepositoryPool
+ env: MockEnv, pool: RepositoryPool, dist_hash_getter: DistributionHashGetter
) -> None:
chooser = Chooser(pool, env)
package = Package(
@@ -463,15 +380,14 @@ def test_chooser_md5_remote_fallback_to_sha256_inline_calculation(
"0.1.0",
source_type="legacy",
source_reference="foo",
- source_url="https://foo.bar/simple/",
+ source_url="https://legacy.foo.bar/simple/",
)
package.files = [
{
- "hash": (
- "sha256:9fa123ad707a5c6c944743bf3e11a0e80d86cb518d3cf25320866ca3ef43e2ad"
- ),
- "filename": "demo-0.1.0.tar.gz",
+ "filename": filename,
+ "hash": (f"sha256:{dist_hash_getter(filename).sha256}"),
}
+ for filename in [f"{package.name}-{package.version}.tar.gz"]
]
res = chooser.choose_for(package)
assert res.filename == "demo-0.1.0.tar.gz"
diff --git a/tests/installation/test_executor.py b/tests/installation/test_executor.py
index a26c90b01c7..b862d3f5141 100644
--- a/tests/installation/test_executor.py
+++ b/tests/installation/test_executor.py
@@ -33,7 +33,6 @@
from poetry.utils.cache import ArtifactCache
from poetry.utils.env import MockEnv
from poetry.vcs.git.backend import Git
-from tests.repositories.test_pypi_repository import MockRepository
if TYPE_CHECKING:
@@ -43,6 +42,7 @@
from poetry.config.config import Config
from poetry.installation.operations.operation import Operation
+ from poetry.repositories.pypi_repository import PyPiRepository
from poetry.utils.env import VirtualEnv
from tests.types import FixtureDirGetter
@@ -123,9 +123,11 @@ def io_not_decorated() -> BufferedIO:
@pytest.fixture
-def pool() -> RepositoryPool:
+def pool(pypi_repository: PyPiRepository) -> RepositoryPool:
pool = RepositoryPool()
- pool.add_repository(MockRepository())
+
+ pypi_repository._fallback = True
+ pool.add_repository(pypi_repository)
return pool
@@ -161,7 +163,6 @@ def test_execute_executes_a_batch_of_operations(
pool: RepositoryPool,
io: BufferedIO,
tmp_path: Path,
- mock_file_downloads: None,
env: MockEnv,
copy_wheel: Callable[[], Path],
fixture_dir: FixtureDirGetter,
@@ -274,7 +275,6 @@ def test_execute_prints_warning_for_yanked_package(
pool: RepositoryPool,
io: BufferedIO,
tmp_path: Path,
- mock_file_downloads: None,
env: MockEnv,
operations: list[Operation],
has_warning: bool,
@@ -308,7 +308,6 @@ def test_execute_prints_warning_for_invalid_wheels(
pool: RepositoryPool,
io: BufferedIO,
tmp_path: Path,
- mock_file_downloads: None,
env: MockEnv,
) -> None:
config.merge({"cache-dir": str(tmp_path)})
@@ -423,7 +422,6 @@ def test_execute_works_with_ansi_output(
pool: RepositoryPool,
io_decorated: BufferedIO,
tmp_path: Path,
- mock_file_downloads: None,
env: MockEnv,
) -> None:
config.merge({"cache-dir": str(tmp_path)})
@@ -460,7 +458,6 @@ def test_execute_works_with_no_ansi_output(
pool: RepositoryPool,
io_not_decorated: BufferedIO,
tmp_path: Path,
- mock_file_downloads: None,
env: MockEnv,
) -> None:
config.merge({"cache-dir": str(tmp_path)})
@@ -547,7 +544,6 @@ def test_executor_should_delete_incomplete_downloads(
tmp_path: Path,
mocker: MockerFixture,
pool: RepositoryPool,
- mock_file_downloads: None,
env: MockEnv,
) -> None:
cached_archive = tmp_path / "tomlkit-0.5.3-py2.py3-none-any.whl"
@@ -694,7 +690,6 @@ def test_executor_should_write_pep610_url_references_for_non_wheel_files(
config: Config,
io: BufferedIO,
fixture_dir: FixtureDirGetter,
- mock_file_downloads: None,
) -> None:
url = (fixture_dir("distributions") / "demo-0.1.0.tar.gz").resolve()
package = Package("demo", "0.1.0", source_type="file", source_url=url.as_posix())
@@ -790,7 +785,6 @@ def test_executor_should_write_pep610_url_references_for_wheel_urls(
pool: RepositoryPool,
config: Config,
io: BufferedIO,
- mock_file_downloads: None,
mocker: MockerFixture,
fixture_dir: FixtureDirGetter,
is_artifact_cached: bool,
@@ -866,7 +860,6 @@ def test_executor_should_write_pep610_url_references_for_non_wheel_urls(
pool: RepositoryPool,
config: Config,
io: BufferedIO,
- mock_file_downloads: None,
mocker: MockerFixture,
fixture_dir: FixtureDirGetter,
is_sdist_cached: bool,
@@ -953,7 +946,6 @@ def test_executor_should_write_pep610_url_references_for_git(
config: Config,
artifact_cache: ArtifactCache,
io: BufferedIO,
- mock_file_downloads: None,
wheel: Path,
mocker: MockerFixture,
fixture_dir: FixtureDirGetter,
@@ -1017,7 +1009,6 @@ def test_executor_should_write_pep610_url_references_for_editable_git(
config: Config,
artifact_cache: ArtifactCache,
io: BufferedIO,
- mock_file_downloads: None,
wheel: Path,
mocker: MockerFixture,
fixture_dir: FixtureDirGetter,
@@ -1066,7 +1057,6 @@ def test_executor_should_append_subdirectory_for_git(
config: Config,
artifact_cache: ArtifactCache,
io: BufferedIO,
- mock_file_downloads: None,
wheel: Path,
) -> None:
package = Package(
@@ -1097,7 +1087,6 @@ def test_executor_should_write_pep610_url_references_for_git_with_subdirectories
config: Config,
artifact_cache: ArtifactCache,
io: BufferedIO,
- mock_file_downloads: None,
wheel: Path,
) -> None:
package = Package(
@@ -1168,7 +1157,6 @@ def test_executor_fallback_on_poetry_create_error_without_wheel_installer(
pool: RepositoryPool,
io: BufferedIO,
tmp_path: Path,
- mock_file_downloads: None,
env: MockEnv,
fixture_dir: FixtureDirGetter,
) -> None:
@@ -1244,7 +1232,6 @@ def test_build_backend_errors_are_reported_correctly_if_caused_by_subprocess(
config: Config,
pool: RepositoryPool,
io: BufferedIO,
- mock_file_downloads: None,
env: MockEnv,
fixture_dir: FixtureDirGetter,
) -> None:
@@ -1313,7 +1300,6 @@ def test_build_backend_errors_are_reported_correctly_if_caused_by_subprocess_enc
config: Config,
pool: RepositoryPool,
io: BufferedIO,
- mock_file_downloads: None,
env: MockEnv,
fixture_dir: FixtureDirGetter,
) -> None:
@@ -1349,7 +1335,6 @@ def test_build_system_requires_not_available(
config: Config,
pool: RepositoryPool,
io: BufferedIO,
- mock_file_downloads: None,
env: MockEnv,
fixture_dir: FixtureDirGetter,
) -> None:
@@ -1395,7 +1380,6 @@ def test_build_system_requires_install_failure(
config: Config,
pool: RepositoryPool,
io: BufferedIO,
- mock_file_downloads: None,
env: MockEnv,
fixture_dir: FixtureDirGetter,
) -> None:
@@ -1450,7 +1434,6 @@ def test_other_error(
config: Config,
pool: RepositoryPool,
io: BufferedIO,
- mock_file_downloads: None,
env: MockEnv,
fixture_dir: FixtureDirGetter,
) -> None:
@@ -1562,7 +1545,6 @@ def test_executor_known_hashes(
config: Config,
io: BufferedIO,
fixture_dir: FixtureDirGetter,
- mock_file_downloads: None,
) -> None:
# when installing sdist, an isolated build environment is required to extract metadata
# this will install any build system requirements into the environment, to avoid failures when
diff --git a/tests/installation/test_installer.py b/tests/installation/test_installer.py
index d27d2166162..0e526b741b2 100644
--- a/tests/installation/test_installer.py
+++ b/tests/installation/test_installer.py
@@ -33,16 +33,14 @@
from tests.helpers import MOCK_DEFAULT_GIT_REVISION
from tests.helpers import get_dependency
from tests.helpers import get_package
-from tests.repositories.test_legacy_repository import (
- MockRepository as MockLegacyRepository,
-)
-from tests.repositories.test_pypi_repository import MockRepository
if TYPE_CHECKING:
from pytest_mock import MockerFixture
from poetry.installation.operations.operation import Operation
+ from poetry.repositories.legacy_repository import LegacyRepository
+ from poetry.repositories.pypi_repository import PyPiRepository
from poetry.utils.env import Env
from tests.conftest import Config
from tests.types import FixtureDirGetter
@@ -1097,16 +1095,16 @@ def test_run_installs_extras_with_deps_if_requested(
assert installer.executor.removals_count == expected_removals_count
-@pytest.mark.network
def test_installer_with_pypi_repository(
package: ProjectPackage,
locker: Locker,
installed: CustomInstalledRepository,
config: Config,
env: NullEnv,
+ pypi_repository: PyPiRepository,
) -> None:
pool = RepositoryPool()
- pool.add_repository(MockRepository())
+ pool.add_repository(pypi_repository)
installer = Installer(
NullIO(), env, package, locker, pool, config, installed=installed
@@ -1118,7 +1116,6 @@ def test_installer_with_pypi_repository(
assert result == 0
expected = fixture("with-pypi-repository")
-
assert expected == locker.written_data
@@ -1901,11 +1898,12 @@ def test_installer_required_extras_should_not_be_removed_when_updating_single_de
env: NullEnv,
mocker: MockerFixture,
config: Config,
+ pypi_repository: PyPiRepository,
) -> None:
mocker.patch("sys.platform", "darwin")
pool = RepositoryPool()
- pool.add_repository(MockRepository())
+ pool.add_repository(pypi_repository)
installer = Installer(
NullIO(),
@@ -1964,9 +1962,10 @@ def test_installer_required_extras_should_be_installed(
installed: CustomInstalledRepository,
env: NullEnv,
config: Config,
+ pypi_repository: PyPiRepository,
) -> None:
pool = RepositoryPool()
- pool.add_repository(MockRepository())
+ pool.add_repository(pypi_repository)
installer = Installer(
NullIO(),
@@ -2100,6 +2099,8 @@ def test_installer_can_install_dependencies_from_forced_source(
installed: CustomInstalledRepository,
env: NullEnv,
config: Config,
+ legacy_repository: LegacyRepository,
+ pypi_repository: PyPiRepository,
) -> None:
package.python_versions = "^3.7"
package.add_dependency(
@@ -2107,8 +2108,8 @@ def test_installer_can_install_dependencies_from_forced_source(
)
pool = RepositoryPool()
- pool.add_repository(MockLegacyRepository())
- pool.add_repository(MockRepository())
+ pool.add_repository(legacy_repository)
+ pool.add_repository(pypi_repository)
installer = Installer(
NullIO(),
@@ -2235,9 +2236,10 @@ def test_installer_can_handle_old_lock_files(
repo: Repository,
installed: CustomInstalledRepository,
config: Config,
+ pypi_repository: PyPiRepository,
) -> None:
pool = RepositoryPool()
- pool.add_repository(MockRepository())
+ pool.add_repository(pypi_repository)
package.add_dependency(Factory.create_dependency("pytest", "^3.5", groups=["dev"]))
diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py
new file mode 100644
index 00000000000..c3d0fdfd765
--- /dev/null
+++ b/tests/integration/conftest.py
@@ -0,0 +1,14 @@
+from __future__ import annotations
+
+from typing import TYPE_CHECKING
+
+import pytest
+
+
+if TYPE_CHECKING:
+ import httpretty
+
+
+@pytest.fixture(autouse=True)
+def disable_httpretty(http: type[httpretty.httpretty]) -> None:
+ http.disable()
diff --git a/tests/puzzle/test_solver.py b/tests/puzzle/test_solver.py
index c9e4c6db7a0..7495ad29a1e 100644
--- a/tests/puzzle/test_solver.py
+++ b/tests/puzzle/test_solver.py
@@ -31,10 +31,6 @@
from tests.helpers import MOCK_DEFAULT_GIT_REVISION
from tests.helpers import get_dependency
from tests.helpers import get_package
-from tests.repositories.test_legacy_repository import (
- MockRepository as MockLegacyRepository,
-)
-from tests.repositories.test_pypi_repository import MockRepository as MockPyPIRepository
if TYPE_CHECKING:
@@ -45,6 +41,8 @@
from poetry.installation.operations.operation import Operation
from poetry.puzzle.provider import Provider
from poetry.puzzle.transaction import Transaction
+ from poetry.repositories.legacy_repository import LegacyRepository
+ from poetry.repositories.pypi_repository import PyPiRepository
from tests.types import FixtureDirGetter
DEFAULT_SOURCE_REF = (
@@ -2944,9 +2942,9 @@ def test_solver_can_resolve_wheel_dependencies_with_extras(
def test_solver_can_solve_with_legacy_repository_using_proper_dists(
- package: ProjectPackage, io: NullIO
+ package: ProjectPackage, io: NullIO, legacy_repository: LegacyRepository
) -> None:
- repo = MockLegacyRepository()
+ repo = legacy_repository
pool = RepositoryPool([repo])
solver = Solver(package, pool, [], [], io)
@@ -2988,10 +2986,11 @@ def test_solver_can_solve_with_legacy_repository_using_proper_dists(
def test_solver_can_solve_with_legacy_repository_using_proper_python_compatible_dists(
package: ProjectPackage,
io: NullIO,
+ legacy_repository: LegacyRepository,
) -> None:
package.python_versions = "^3.7"
- repo = MockLegacyRepository()
+ repo = legacy_repository
pool = RepositoryPool([repo])
solver = Solver(package, pool, [], [], io)
@@ -3017,11 +3016,12 @@ def test_solver_can_solve_with_legacy_repository_using_proper_python_compatible_
)
-def test_solver_skips_invalid_versions(package: ProjectPackage, io: NullIO) -> None:
+def test_solver_skips_invalid_versions(
+ package: ProjectPackage, io: NullIO, pypi_repository: PyPiRepository
+) -> None:
package.python_versions = "^3.7"
- repo = MockPyPIRepository()
- pool = RepositoryPool([repo])
+ pool = RepositoryPool([pypi_repository])
solver = Solver(package, pool, [], [], io)
@@ -3059,13 +3059,15 @@ def test_multiple_constraints_on_root(
def test_solver_chooses_most_recent_version_amongst_repositories(
- package: ProjectPackage, io: NullIO
+ package: ProjectPackage,
+ io: NullIO,
+ legacy_repository: LegacyRepository,
+ pypi_repository: PyPiRepository,
) -> None:
package.python_versions = "^3.7"
package.add_dependency(Factory.create_dependency("tomlkit", {"version": "^0.5"}))
- repo = MockLegacyRepository()
- pool = RepositoryPool([repo, MockPyPIRepository()])
+ pool = RepositoryPool([legacy_repository, pypi_repository])
solver = Solver(package, pool, [], [], io)
@@ -3080,15 +3082,17 @@ def test_solver_chooses_most_recent_version_amongst_repositories(
def test_solver_chooses_from_correct_repository_if_forced(
- package: ProjectPackage, io: NullIO
+ package: ProjectPackage,
+ io: NullIO,
+ legacy_repository: LegacyRepository,
+ pypi_repository: PyPiRepository,
) -> None:
package.python_versions = "^3.7"
package.add_dependency(
Factory.create_dependency("tomlkit", {"version": "^0.5", "source": "legacy"})
)
- repo = MockLegacyRepository()
- pool = RepositoryPool([repo, MockPyPIRepository()])
+ pool = RepositoryPool([legacy_repository, pypi_repository])
solver = Solver(package, pool, [], [], io)
@@ -3103,19 +3107,21 @@ def test_solver_chooses_from_correct_repository_if_forced(
"tomlkit",
"0.5.2",
source_type="legacy",
- source_url=repo.url,
- source_reference=repo.name,
+ source_url=legacy_repository.url,
+ source_reference=legacy_repository.name,
),
}
],
)
- assert ops[0].package.source_url == "http://legacy.foo.bar"
+ assert ops[0].package.source_url == legacy_repository.url
def test_solver_chooses_from_correct_repository_if_forced_and_transitive_dependency(
package: ProjectPackage,
io: NullIO,
+ legacy_repository: LegacyRepository,
+ pypi_repository: PyPiRepository,
) -> None:
package.python_versions = "^3.7"
package.add_dependency(Factory.create_dependency("foo", "^1.0"))
@@ -3127,7 +3133,8 @@ def test_solver_chooses_from_correct_repository_if_forced_and_transitive_depende
foo = get_package("foo", "1.0.0")
foo.add_dependency(Factory.create_dependency("tomlkit", "^0.5.0"))
repo.add_package(foo)
- pool = RepositoryPool([MockLegacyRepository(), repo, MockPyPIRepository()])
+
+ pool = RepositoryPool([legacy_repository, repo, pypi_repository])
solver = Solver(package, pool, [], [], io)
@@ -3142,7 +3149,7 @@ def test_solver_chooses_from_correct_repository_if_forced_and_transitive_depende
"tomlkit",
"0.5.2",
source_type="legacy",
- source_url="http://legacy.foo.bar",
+ source_url=legacy_repository.url,
source_reference="legacy",
),
},
@@ -3150,21 +3157,24 @@ def test_solver_chooses_from_correct_repository_if_forced_and_transitive_depende
],
)
- assert ops[0].package.source_url == "http://legacy.foo.bar"
+ assert ops[0].package.source_url == legacy_repository.url
assert ops[1].package.source_type is None
assert ops[1].package.source_url is None
def test_solver_does_not_choose_from_secondary_repository_by_default(
- package: ProjectPackage, io: NullIO
+ package: ProjectPackage,
+ io: NullIO,
+ legacy_repository: LegacyRepository,
+ pypi_repository: PyPiRepository,
) -> None:
package.python_versions = "^3.7"
package.add_dependency(Factory.create_dependency("clikit", {"version": "^0.2.0"}))
pool = RepositoryPool()
- pool.add_repository(MockPyPIRepository(), priority=Priority.SECONDARY)
- pool.add_repository(MockLegacyRepository())
+ pool.add_repository(pypi_repository, priority=Priority.SECONDARY)
+ pool.add_repository(legacy_repository)
solver = Solver(package, pool, [], [], io)
@@ -3179,7 +3189,7 @@ def test_solver_does_not_choose_from_secondary_repository_by_default(
"pastel",
"0.1.0",
source_type="legacy",
- source_url="http://legacy.foo.bar",
+ source_url=legacy_repository.url,
source_reference="legacy",
),
},
@@ -3190,22 +3200,24 @@ def test_solver_does_not_choose_from_secondary_repository_by_default(
"clikit",
"0.2.4",
source_type="legacy",
- source_url="http://legacy.foo.bar",
+ source_url=legacy_repository.url,
source_reference="legacy",
),
},
],
)
- assert ops[0].package.source_url == "http://legacy.foo.bar"
+ assert ops[0].package.source_url == legacy_repository.url
assert ops[1].package.source_type is None
assert ops[1].package.source_url is None
- assert ops[2].package.source_url == "http://legacy.foo.bar"
+ assert ops[2].package.source_url == legacy_repository.url
def test_solver_chooses_from_secondary_if_explicit(
package: ProjectPackage,
io: NullIO,
+ legacy_repository: LegacyRepository,
+ pypi_repository: PyPiRepository,
) -> None:
package.python_versions = "^3.7"
package.add_dependency(
@@ -3213,8 +3225,8 @@ def test_solver_chooses_from_secondary_if_explicit(
)
pool = RepositoryPool()
- pool.add_repository(MockPyPIRepository(), priority=Priority.SECONDARY)
- pool.add_repository(MockLegacyRepository())
+ pool.add_repository(pypi_repository, priority=Priority.SECONDARY)
+ pool.add_repository(legacy_repository)
solver = Solver(package, pool, [], [], io)
@@ -3229,7 +3241,7 @@ def test_solver_chooses_from_secondary_if_explicit(
"pastel",
"0.1.0",
source_type="legacy",
- source_url="http://legacy.foo.bar",
+ source_url=legacy_repository.url,
source_reference="legacy",
),
},
@@ -3238,7 +3250,7 @@ def test_solver_chooses_from_secondary_if_explicit(
],
)
- assert ops[0].package.source_url == "http://legacy.foo.bar"
+ assert ops[0].package.source_url == legacy_repository.url
assert ops[1].package.source_type is None
assert ops[1].package.source_url is None
assert ops[2].package.source_type is None
@@ -3246,14 +3258,17 @@ def test_solver_chooses_from_secondary_if_explicit(
def test_solver_does_not_choose_from_explicit_repository(
- package: ProjectPackage, io: NullIO
+ package: ProjectPackage,
+ io: NullIO,
+ legacy_repository: LegacyRepository,
+ pypi_repository: PyPiRepository,
) -> None:
package.python_versions = "^3.7"
package.add_dependency(Factory.create_dependency("attrs", {"version": "^17.4.0"}))
pool = RepositoryPool()
- pool.add_repository(MockPyPIRepository(), priority=Priority.EXPLICIT)
- pool.add_repository(MockLegacyRepository())
+ pool.add_repository(pypi_repository, priority=Priority.EXPLICIT)
+ pool.add_repository(legacy_repository)
solver = Solver(package, pool, [], [], io)
@@ -3264,6 +3279,8 @@ def test_solver_does_not_choose_from_explicit_repository(
def test_solver_chooses_direct_dependency_from_explicit_if_explicit(
package: ProjectPackage,
io: NullIO,
+ legacy_repository: LegacyRepository,
+ pypi_repository: PyPiRepository,
) -> None:
package.python_versions = "^3.7"
package.add_dependency(
@@ -3271,8 +3288,8 @@ def test_solver_chooses_direct_dependency_from_explicit_if_explicit(
)
pool = RepositoryPool()
- pool.add_repository(MockPyPIRepository(), priority=Priority.EXPLICIT)
- pool.add_repository(MockLegacyRepository())
+ pool.add_repository(pypi_repository, priority=Priority.EXPLICIT)
+ pool.add_repository(legacy_repository)
solver = Solver(package, pool, [], [], io)
@@ -3292,17 +3309,19 @@ def test_solver_chooses_direct_dependency_from_explicit_if_explicit(
def test_solver_ignores_explicit_repo_for_transient_dependencies(
package: ProjectPackage,
io: NullIO,
+ legacy_repository: LegacyRepository,
+ pypi_repository: PyPiRepository,
) -> None:
- # clikit depends on pylev, which is in MockPyPIRepository (explicit) but not in
- # MockLegacyRepository
+ # clikit depends on pylev, which is in pypi_repository (explicit) but not in
+ # legacy_repository
package.python_versions = "^3.7"
package.add_dependency(
Factory.create_dependency("clikit", {"version": "^0.2.0", "source": "PyPI"})
)
pool = RepositoryPool()
- pool.add_repository(MockPyPIRepository(), priority=Priority.EXPLICIT)
- pool.add_repository(MockLegacyRepository())
+ pool.add_repository(pypi_repository, priority=Priority.EXPLICIT)
+ pool.add_repository(legacy_repository)
solver = Solver(package, pool, [], [], io)
diff --git a/tests/repositories/conftest.py b/tests/repositories/conftest.py
index 1f9a6d11946..2661b46fc20 100644
--- a/tests/repositories/conftest.py
+++ b/tests/repositories/conftest.py
@@ -1,18 +1,12 @@
from __future__ import annotations
-import posixpath
-
-from pathlib import Path
from typing import TYPE_CHECKING
-from typing import Any
import pytest
-import requests
if TYPE_CHECKING:
from tests.types import HTMLPageGetter
- from tests.types import RequestsSessionGet
@pytest.fixture
@@ -35,25 +29,3 @@ def _fixture(content: str, base_url: str | None = None) -> str:
"""
return _fixture
-
-
-@pytest.fixture
-def get_metadata_mock() -> RequestsSessionGet:
- def metadata_mock(url: str, **__: Any) -> requests.Response:
- if url.endswith(".metadata"):
- response = requests.Response()
- response.encoding = "application/text"
- response._content = (
- (
- Path(__file__).parent
- / "fixtures"
- / "metadata"
- / posixpath.basename(url)
- )
- .read_text()
- .encode()
- )
- return response
- raise requests.HTTPError()
-
- return metadata_mock
diff --git a/tests/repositories/fixtures/__init__.py b/tests/repositories/fixtures/__init__.py
new file mode 100644
index 00000000000..a398ab3e8a2
--- /dev/null
+++ b/tests/repositories/fixtures/__init__.py
@@ -0,0 +1,9 @@
+from __future__ import annotations
+
+
+pytest_plugins = [
+ "tests.repositories.fixtures.distribution_hashes",
+ "tests.repositories.fixtures.legacy",
+ "tests.repositories.fixtures.pypi",
+ "tests.repositories.fixtures.python_hosted",
+]
diff --git a/tests/repositories/fixtures/distribution_hashes.py b/tests/repositories/fixtures/distribution_hashes.py
new file mode 100644
index 00000000000..6c20ed308bf
--- /dev/null
+++ b/tests/repositories/fixtures/distribution_hashes.py
@@ -0,0 +1,302 @@
+# this file is generated by tests/repositories/fixtures/pypi.org/generate.py
+from __future__ import annotations
+
+import dataclasses
+
+from typing import TYPE_CHECKING
+
+import pytest
+
+
+if TYPE_CHECKING:
+ from tests.types import DistributionHashGetter
+
+
+@dataclasses.dataclass
+class DistributionHash:
+ sha256: str = ""
+ md5: str = ""
+
+
+KNOWN_DISTRIBUTION_HASHES = {
+ "SQLAlchemy-1.2.12.tar.gz": DistributionHash(
+ "b5a127599b3f27847fba6119de0fcb70832a8041b103701a708b7c7d044faa38",
+ "4a2617b5254748828d09349fc4eff6bd",
+ ),
+ "Twisted-18.9.0.tar.bz2": DistributionHash(
+ "4335327da58be11dd6e482ec6b85eb055bcc953a9570cd59e7840a2ce9419a8e",
+ "35ff4705ea90a76bf972ff3b229546ca",
+ ),
+ "attrs-17.4.0-py2.py3-none-any.whl": DistributionHash(
+ "d38e57f381e891928357c68e300d28d3d4dcddc50486d5f8dfaf743d40477619",
+ "9d32f2b5a93343e01f54d87740f2da60",
+ ),
+ "attrs-17.4.0.tar.gz": DistributionHash(
+ "eb7536a1e6928190b3008c5b350bdf9850d619fff212341cd096f87a27a5e564",
+ "c03e5b3608d9071fbd098850d8922668",
+ ),
+ "black-19.10b0-py36-none-any.whl": DistributionHash(
+ "3471ff321348d851b6f3047f4ed42c88622ac038caf7c2d160bd653334c88e88",
+ "4a420234749e1ea350581160ef51cd02",
+ ),
+ "black-19.10b0.tar.gz": DistributionHash(
+ "6cada614d5d2132698c6d5fff384657273d922c4fffa6a2f0de9e03e25b8913a",
+ "c383543109a66a5a99113e6326db5251",
+ ),
+ "black-21.11b0-py3-none-any.whl": DistributionHash(
+ "e16b6879ed61f9268994b879174fad1cb2319a651afd20f8cf036428ac65f846",
+ "294e105f34e2e21286a49bfcfb8fb6ae",
+ ),
+ "black-21.11b0.tar.gz": DistributionHash(
+ "f23c482185d842e2f19d506e55c004061167e3c677c063ecd721042c62086ada",
+ "f01267bf2613f825dd6684629c1c829e",
+ ),
+ "cleo-1.0.0a5-py3-none-any.whl": DistributionHash(
+ "20dbd69ed5c27e2889a2d428b9b01771f6073e4a1483a731e3c14c07a666aa9f",
+ "eaf14b3f99b2b88c0846ecc9a5a18af4",
+ ),
+ "cleo-1.0.0a5.tar.gz": DistributionHash(
+ "88f0a4275a17f2ab4d013786b8b9522d4c60bd37d8fc9b3def0fb27f4ac1e694",
+ "92e181952976e09b9d1c583da6c3e2fc",
+ ),
+ "clikit-0.2.4-py2.py3-none-any.whl": DistributionHash(
+ "60900adbac91d6d2cefc88efe2639ce3090f4520106596ac855bee3763f276c0",
+ "c3558fef2a1148bb1df96376def5c8fe",
+ ),
+ "clikit-0.2.4.tar.gz": DistributionHash(
+ "0fdd41e86e8b118a8b1e94ef2835925ada541d481c9b3b2fc635fa68713e6125",
+ "f7cdbad3508038a04561f646aae68146",
+ ),
+ "colorama-0.3.9-py2.py3-none-any.whl": DistributionHash(
+ "5b632359f1ed2b7676a869812ba0edaacb99be04679b29eb56c07a5e137ab5a2",
+ "faef2bbd3c2ecc43e0969877d67b4c92",
+ ),
+ "colorama-0.3.9.tar.gz": DistributionHash(
+ "4c5a15209723ce1330a5c193465fe221098f761e9640d823a2ce7c03f983137f",
+ "8323a5b84fdf7ad810804e51fc256b39",
+ ),
+ "demo-0.1.0-py2.py3-none-any.whl": DistributionHash(
+ "70e704135718fffbcbf61ed1fc45933cfd86951a744b681000eaaa75da31f17a",
+ "15507846fd4299596661d0197bfb4f90",
+ ),
+ "demo-0.1.0.tar.gz": DistributionHash(
+ "9fa123ad707a5c6c944743bf3e11a0e80d86cb518d3cf25320866ca3ef43e2ad",
+ "d1912c917363a64e127318655f7d1fe7",
+ ),
+ "demo-0.1.2-py2.py3-none-any.whl": DistributionHash(
+ "55dde4e6828081de7a1e429f33180459c333d9da593db62a3d75a8f5e505dde1",
+ "53b4e10d2bfa81a4206221c4b87843d9",
+ ),
+ "demo_invalid_record-0.1.0-py2.py3-none-any.whl": DistributionHash(
+ "d1e5a3f18f24a2ad3717c6f9c55f8c26060f39b2cddf28b18c355786728cb4dd",
+ "18041168d415370d5019ec7e2b1ed0b5",
+ ),
+ "demo_invalid_record2-0.1.0-py2.py3-none-any.whl": DistributionHash(
+ "e730fca385b52e77fc58d73812f0dc236fad489ef6026716d1a4317ab4738c3c",
+ "a21ee67e833f50e9f0ecdfe1c0484b93",
+ ),
+ "demo_metadata_version_23-0.1.0-py2.py3-none-any.whl": DistributionHash(
+ "7592aa158137726d9579e5d4347bd03a88f9fc82e11061303215feaaf000d32c",
+ "434114a36f986671d132033e130f26b7",
+ ),
+ "demo_missing_dist_info-0.1.0-py2.py3-none-any.whl": DistributionHash(
+ "cf8eaade81dd1db42f60c0e9c8610c1c12006baa9f7ad994b1c2bae92ea4b426",
+ "da33c6088e72fbaaf873999606767353",
+ ),
+ "demo_no_pkg_info-0.1.0.tar.gz": DistributionHash(
+ "f1e2a977c506dfb6b43495e2ffeee618b90029bac92fcb3038a53268197afa0c",
+ "eeaf257d6b2c3b01def567751b21c1e8",
+ ),
+ "discord.py-2.0.0-py3-none-any.whl": DistributionHash(
+ "054c3d8cf89a8e37a691e0268232dad23e07f4e9a06f33454c3bafeaba34a9b7",
+ "8ffc907807f8351401dbe4408dcaff79",
+ ),
+ "discord.py-2.0.0.tar.gz": DistributionHash(
+ "b86fa9dd562684f7a52564e6dfe0216f6c172a009c0d86b8dea8bdd6ffa6b1f4",
+ "6c0505a6032342b29f31f9979f37d277",
+ ),
+ "futures-3.2.0-py2-none-any.whl": DistributionHash(
+ "d89e1540e8b553fbda912230db359954365a1f5d0d0fa7fab96ad3969d9d5a93",
+ "33e76564a87766c3e186d986ddc55bd8",
+ ),
+ "futures-3.2.0.tar.gz": DistributionHash(
+ "baf0d469c9e541b747986b7404cd63a5496955bd0c43a3cc068c449b09b7d4a4",
+ "40eb168dab84e606df3fdb7e67fe27b7",
+ ),
+ "ipython-5.7.0-py2-none-any.whl": DistributionHash(
+ "3d93d3995e2e52a98dc4f44361cd5bf68dbde62925d1f820b97d8f0e1d941f73",
+ "cf35939995e0fd8c44fca7509308abde",
+ ),
+ "ipython-5.7.0-py3-none-any.whl": DistributionHash(
+ "b94c7a3971290024ffaa916d51ee377ee85f8860a62b5f30c58f5376f0956a06",
+ "8805d83c415de06f5eadd55aeb2fa738",
+ ),
+ "ipython-5.7.0.tar.gz": DistributionHash(
+ "4e7fb265e0264498bd0d62c6261936a658bf3d38beb8a7b10cd2c6327c62ac2a",
+ "01f2808ebe78ff2f28dc39be3aa635ca",
+ ),
+ "ipython-7.5.0-py3-none-any.whl": DistributionHash(
+ "634f505893bbbdb79d1a04d89f4633d8cfc41115337847fbf9d5a23610fc3e3d",
+ "99a386eca39b536033c71aacf9f98e2b",
+ ),
+ "ipython-7.5.0.tar.gz": DistributionHash(
+ "cd2a17ac273fea8bf8953118a2d83bad94f592f0db3e83fff9129a1842e36dbe",
+ "0e8c1d7c14f309f6cd2dfd4e48e75cb1",
+ ),
+ "isort-4.3.4-py2-none-any.whl": DistributionHash(
+ "3bbfc8f6119a46a48064487afb0b3ca9daa4b09fbfd94336a24c7616b71db2ca",
+ "e84fb6f2278ee4d0bd719a4d44863d9f",
+ ),
+ "isort-4.3.4-py3-none-any.whl": DistributionHash(
+ "e7aa083302c758b358e10a3a1c707adcc9f8ab57795e99246ac72eeffe7f2b20",
+ "baa2e5dc4e89511b6bc54e969d040a08",
+ ),
+ "isort-4.3.4.tar.gz": DistributionHash(
+ "234ad07e1e2780c27fa56364eefa734bee991b0d744337ef7e7ce3d5b1b59f39",
+ "9244631852cf8bd8559f7ab78bf4ec78",
+ ),
+ "jupyter-1.0.0-py2.py3-none-any.whl": DistributionHash(
+ "83c4591b9c7392ea5f91e0d9f8e98d894f76e8e669260788f0fcb281ec0b3b1f",
+ "b2f5e2daab779c7bda0be38925ab1b92",
+ ),
+ "jupyter-1.0.0.tar.gz": DistributionHash(
+ "3ef1e86ba0556ea5922b846416a41acfd2625830d996c7d06d80c90bed1dc193",
+ "78acaec88533ea6b6e761e7d086a1d04",
+ ),
+ "jupyter-1.0.0.zip": DistributionHash(
+ "4a855b9717c3ea24fd8ca4fd91ab5995894aecc4d20e7f39c28786a2c1869fae",
+ "7b7a957694a73ac0c19fe46c216c0ea0",
+ ),
+ "more-itertools-4.1.0.tar.gz": DistributionHash(
+ "bab2dc6f4be8f9a4a72177842c5283e2dff57c167439a03e3d8d901e854f0f2e",
+ "bf351a1050242ce3af7e475a4da1a26b",
+ ),
+ "more_itertools-4.1.0-py2-none-any.whl": DistributionHash(
+ "5dd7dfd88d2fdaea446da478ffef8d7151fdf26ee92ac7ed7b14e8d71efe4b62",
+ "c70269eabc5fae5e0d93c2eca638720e",
+ ),
+ "more_itertools-4.1.0-py3-none-any.whl": DistributionHash(
+ "29b1e1661aaa56875ce090fa219fa84dfc13daecb52cd4fae321f6f57b419ec4",
+ "26d7c309ef806b4e563d2a7e4ceafb14",
+ ),
+ "pastel-0.1.0-py3-none-any.whl": DistributionHash(
+ "d88b34efa115392ee42c55d6f82cdf5e5e08221ef2e18a16ae696a80008c3499",
+ "632fcf45cc28aed4a4dce1324d1bd1d1",
+ ),
+ "pastel-0.1.0.tar.gz": DistributionHash(
+ "22f14474c4120b37c54ac2173b49b0ac1de9283ca714be6eb3ea8b39296285a9",
+ "43ea5f07660f630da18ae1827f5b4333",
+ ),
+ "pluggy-0.6.0-py2-none-any.whl": DistributionHash(
+ "9b835f86bfe5498c87ace7f4899cb1b0c40e71c9277377f6851c74a307879285",
+ "de6f342e8044d0071eefc3c9cda33055",
+ ),
+ "pluggy-0.6.0-py3-none-any.whl": DistributionHash(
+ "8c646771f5eab7557d1f3924077c55408e86bdfb700f7d86a6d83abeabff4c66",
+ "f2fc2c3179edccaa7728650178c9133c",
+ ),
+ "pluggy-0.6.0.tar.gz": DistributionHash(
+ "a982e208d054867661d27c6d2a86b17ba05fbb6b1bdc01f42660732dd107f865",
+ "ef8a88abcd501afd47cb22245fe4315a",
+ ),
+ "poetry_core-1.5.0-py3-none-any.whl": DistributionHash(
+ "e216b70f013c47b82a72540d34347632c5bfe59fd54f5fe5d51f6a68b19aaf84",
+ "be7589b4902793e66d7d979bd8581591",
+ ),
+ "poetry_core-1.5.0.tar.gz": DistributionHash(
+ "0ae8d28caf5c12ec1714b16d2e7157ddd52397ea6bfdeba5a9432e449a0184da",
+ "3f9b36a7a94cd235bfd5f05794828445",
+ ),
+ "py-1.5.3-py2.py3-none-any.whl": DistributionHash(
+ "43ee6c7f95e0ec6a906de49906b79d138d89728fff17109d49f086abc2fdd985",
+ "98652ecee6fc3bb5393a17828f93e1fb",
+ ),
+ "py-1.5.3.tar.gz": DistributionHash(
+ "2df2c513c3af11de15f58189ba5539ddc4768c6f33816dc5c03950c8bd6180fa",
+ "623e80cfc06df930414a9ce4bf0fd6c9",
+ ),
+ "pytest-3.5.0-py2.py3-none-any.whl": DistributionHash(
+ "28e4d9c2ae3196d74805c2eba24f350ae4c791a5b9b397c79b41506a48dc64ca",
+ "d3b1e9aea9e5b9e7a226d8b08aa43662",
+ ),
+ "pytest-3.5.0.tar.gz": DistributionHash(
+ "677b1d6decd29c041fe64276f29f79fbe66e40c59e445eb251366b4a8ab8bf68",
+ "ccd78dac54112045f561c4df86631f19",
+ ),
+ "pytest-3.5.1-py2.py3-none-any.whl": DistributionHash(
+ "6d3e83b1c1697d220137e436980e73b3ca674f643e666d7c24b0321cb57b76a4",
+ "f1de372a436700e3a785e85c11d15821",
+ ),
+ "pytest-3.5.1.tar.gz": DistributionHash(
+ "b8fe151f3e181801dd38583a1c03818fbc662a8fce96c9063a0af624613e78f8",
+ "961104636090457187851ccb9ef0f677",
+ ),
+ "python-language-server-0.21.2.tar.gz": DistributionHash(
+ "91b564e092f3135b2bac70dbd23d283da5ad50269766a76648787b69fe702c7e",
+ "677602ec38bc1c7b72de6128d90d846b",
+ ),
+ "requests-2.18.4-py2.py3-none-any.whl": DistributionHash(
+ "ce91d39dc2857eeb19fc8bf765df6c14874bcdc724d3ce9c6cd89915618e7023",
+ "f392c0ab49bf677c6240ef2b1890b079",
+ ),
+ "requests-2.18.4.tar.gz": DistributionHash(
+ "ec62f7e0e9d4814656b0172dbd592fea06127c6556ff5651eb5d2c8768671fd4",
+ "942a6a383dc94da90cf58f5adcf028a4",
+ ),
+ "setuptools-67.6.1-py3-none-any.whl": DistributionHash(
+ "e728ca814a823bf7bf60162daf9db95b93d532948c4c0bea762ce62f60189078",
+ "3b5b846e000da033d54eeaaf7915126e",
+ ),
+ "setuptools-67.6.1.tar.gz": DistributionHash(
+ "a737d365c957dd3fced9ddd246118e95dce7a62c3dc49f37e7fdd9e93475d785",
+ "ee2562f783544d1f95022c906dd3cf98",
+ ),
+ "six-1.11.0-py2.py3-none-any.whl": DistributionHash(
+ "112f5b46e6aa106db3e4e2494a03694c938f41c4c4535edbdfc816c2e0cb50f2",
+ "35b1057b388e276352d0709138b1e194",
+ ),
+ "six-1.11.0.tar.gz": DistributionHash(
+ "268a4ccb159c1a2d2c79336b02e75058387b0cdbb4cea2f07846a758f48a356d",
+ "25d3568604f921dd23532b88a0ce17e7",
+ ),
+ "tomlkit-0.5.2-py2.py3-none-any.whl": DistributionHash(
+ "a50f685abd033a7b50b13330833c15699885186517b713d9f7e8280ce7976e4c",
+ "7bcf6cf4a6034339bb6a481f27b9ba62",
+ ),
+ "tomlkit-0.5.2.tar.gz": DistributionHash(
+ "4a226ccf11ee5a2e76bfc185747b54ee7718706aeb3aabb981327249dbe2b1d4",
+ "7c31987ef6fba2cd64715cae27fade64",
+ ),
+ "tomlkit-0.5.3-py2.py3-none-any.whl": DistributionHash(
+ "d4fe74be9b732d76886da6da2e96f76ae42551e53afce1ea29bc703629b70497",
+ "b868779f054c64bc6c2ae4ad2cdbf6b3",
+ ),
+ "tomlkit-0.5.3.tar.gz": DistributionHash(
+ "e2f785651609492c771d9887ccb2369d891d16595d2d97972e2cbe5e8fb3439f",
+ "cdbdc302a184d1f1e38d5e0810e3b212",
+ ),
+ "wheel-0.40.0-py3-none-any.whl": DistributionHash(
+ "d236b20e7cb522daf2390fa84c55eea81c5c30190f90f29ae2ca1ad8355bf247",
+ "517d39f133bd7b1ff17caf09784b7543",
+ ),
+ "wheel-0.40.0.tar.gz": DistributionHash(
+ "5cb7e75751aa82e1b7db3fd52f5a9d59e7b06905630bed135793295931528740",
+ "5f175a8d693f74878964d4fd29729ab7",
+ ),
+ "zipp-3.5.0-py3-none-any.whl": DistributionHash(
+ "82da6dcae3676123d6f493a876259614e7e6e970b14c59b1830a2c901ed91306",
+ "52aecc0484efd07d62575d152f6a98f6",
+ ),
+ "zipp-3.5.0.tar.gz": DistributionHash(
+ "239d50954a15aa4b283023f18dc451ba811fb4d263f4dd6855642e4d1c80cc9f",
+ "16bf2a24fae340052e8565c264d21092",
+ ),
+}
+
+
+@pytest.fixture
+def dist_hash_getter() -> DistributionHashGetter:
+ def get_hash(name: str) -> DistributionHash:
+ return KNOWN_DISTRIBUTION_HASHES.get(name, DistributionHash())
+
+ return get_hash
diff --git a/tests/repositories/fixtures/legacy.py b/tests/repositories/fixtures/legacy.py
new file mode 100644
index 00000000000..58f431b0268
--- /dev/null
+++ b/tests/repositories/fixtures/legacy.py
@@ -0,0 +1,157 @@
+from __future__ import annotations
+
+import re
+
+from pathlib import Path
+from typing import TYPE_CHECKING
+from typing import Any
+from urllib.parse import urlparse
+
+import pytest
+
+from packaging.utils import canonicalize_name
+
+from poetry.repositories.legacy_repository import LegacyRepository
+from tests.helpers import FIXTURE_PATH_REPOSITORIES_LEGACY
+
+
+if TYPE_CHECKING:
+ import httpretty
+
+ from httpretty.core import HTTPrettyRequest
+ from packaging.utils import NormalizedName
+ from pytest_mock import MockerFixture
+
+ from poetry.repositories.link_sources.html import SimpleRepositoryPage
+ from tests.types import HTTPrettyRequestCallback
+ from tests.types import NormalizedNameTransformer
+ from tests.types import SpecializedLegacyRepositoryMocker
+
+pytest_plugins = [
+ "tests.repositories.fixtures.python_hosted",
+]
+
+
+@pytest.fixture
+def legacy_repository_directory() -> Path:
+ return FIXTURE_PATH_REPOSITORIES_LEGACY
+
+
+@pytest.fixture
+def legacy_repository_package_names(legacy_repository_directory: Path) -> set[str]:
+ return {
+ package_html_file.stem
+ for package_html_file in legacy_repository_directory.glob("*.html")
+ }
+
+
+@pytest.fixture
+def legacy_repository_index_html(
+ legacy_repository_directory: Path, legacy_repository_package_names: set[str]
+) -> str:
+ hrefs = [
+ f'{name}
' for name in legacy_repository_package_names
+ ]
+
+ return f"""
+
+