Commit 2deaf594 by David Hotham Committed by GitHub

tighten typechecking (#6203)

parent 3bd4c7a3
...@@ -410,7 +410,7 @@ class Provider: ...@@ -410,7 +410,7 @@ class Provider:
file_name = os.path.basename(urllib.parse.urlparse(url).path) file_name = os.path.basename(urllib.parse.urlparse(url).path)
with tempfile.TemporaryDirectory() as temp_dir: with tempfile.TemporaryDirectory() as temp_dir:
dest = Path(temp_dir) / file_name dest = Path(temp_dir) / file_name
download_file(url, str(dest)) download_file(url, dest)
package = cls.get_package_from_file(dest) package = cls.get_package_from_file(dest)
package._source_type = "url" package._source_type = "url"
...@@ -528,7 +528,7 @@ class Provider: ...@@ -528,7 +528,7 @@ class Provider:
dependency, dependency,
self._pool.package( self._pool.package(
package.name, package.name,
package.version.text, package.version,
extras=list(dependency.extras), extras=list(dependency.extras),
repository=dependency.source_name, repository=dependency.source_name,
), ),
......
...@@ -13,7 +13,9 @@ from poetry.repositories.repository import Repository ...@@ -13,7 +13,9 @@ from poetry.repositories.repository import Repository
if TYPE_CHECKING: if TYPE_CHECKING:
from packaging.utils import NormalizedName
from poetry.core.packages.package import Package from poetry.core.packages.package import Package
from poetry.core.semver.version import Version
from poetry.inspection.info import PackageInfo from poetry.inspection.info import PackageInfo
...@@ -40,10 +42,12 @@ class CachedRepository(Repository, ABC): ...@@ -40,10 +42,12 @@ class CachedRepository(Repository, ABC):
) )
@abstractmethod @abstractmethod
def _get_release_info(self, name: str, version: str) -> dict[str, Any]: def _get_release_info(
self, name: NormalizedName, version: Version
) -> dict[str, Any]:
raise NotImplementedError() raise NotImplementedError()
def get_release_info(self, name: str, version: str) -> PackageInfo: def get_release_info(self, name: NormalizedName, version: Version) -> PackageInfo:
""" """
Return the release information given a package name and a version. Return the release information given a package name and a version.
...@@ -74,8 +78,8 @@ class CachedRepository(Repository, ABC): ...@@ -74,8 +78,8 @@ class CachedRepository(Repository, ABC):
def package( def package(
self, self,
name: str, name: NormalizedName,
version: str, version: Version,
extras: list[str] | None = None, extras: list[str] | None = None,
) -> Package: ) -> Package:
return self.get_release_info(name, version).to_package(name=name, extras=extras) return self.get_release_info(name, version).to_package(name=name, extras=extras)
...@@ -68,7 +68,7 @@ class HTTPRepository(CachedRepository, ABC): ...@@ -68,7 +68,7 @@ class HTTPRepository(CachedRepository, ABC):
def authenticated_url(self) -> str: def authenticated_url(self) -> str:
return self._authenticator.authenticated_url(url=self.url) return self._authenticator.authenticated_url(url=self.url)
def _download(self, url: str, dest: str) -> None: def _download(self, url: str, dest: Path) -> None:
return download_file(url, dest, session=self.session) return download_file(url, dest, session=self.session)
def _get_info_from_wheel(self, url: str) -> PackageInfo: def _get_info_from_wheel(self, url: str) -> PackageInfo:
...@@ -81,7 +81,7 @@ class HTTPRepository(CachedRepository, ABC): ...@@ -81,7 +81,7 @@ class HTTPRepository(CachedRepository, ABC):
with temporary_directory() as temp_dir: with temporary_directory() as temp_dir:
filepath = Path(temp_dir) / filename filepath = Path(temp_dir) / filename
self._download(url, str(filepath)) self._download(url, filepath)
return PackageInfo.from_wheel(filepath) return PackageInfo.from_wheel(filepath)
...@@ -97,7 +97,7 @@ class HTTPRepository(CachedRepository, ABC): ...@@ -97,7 +97,7 @@ class HTTPRepository(CachedRepository, ABC):
with temporary_directory() as temp_dir: with temporary_directory() as temp_dir:
filepath = Path(temp_dir) / filename filepath = Path(temp_dir) / filename
self._download(url, str(filepath)) self._download(url, filepath)
return PackageInfo.from_sdist(filepath) return PackageInfo.from_sdist(filepath)
...@@ -226,7 +226,7 @@ class HTTPRepository(CachedRepository, ABC): ...@@ -226,7 +226,7 @@ class HTTPRepository(CachedRepository, ABC):
): ):
with temporary_directory() as temp_dir: with temporary_directory() as temp_dir:
filepath = Path(temp_dir) / link.filename filepath = Path(temp_dir) / link.filename
self._download(link.url, str(filepath)) self._download(link.url, filepath)
known_hash = ( known_hash = (
getattr(hashlib, link.hash_name)() if link.hash_name else None getattr(hashlib, link.hash_name)() if link.hash_name else None
......
...@@ -3,9 +3,7 @@ from __future__ import annotations ...@@ -3,9 +3,7 @@ from __future__ import annotations
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from typing import Any from typing import Any
from packaging.utils import canonicalize_name
from poetry.core.packages.package import Package from poetry.core.packages.package import Package
from poetry.core.semver.version import Version
from poetry.inspection.info import PackageInfo from poetry.inspection.info import PackageInfo
from poetry.repositories.exceptions import PackageNotFound from poetry.repositories.exceptions import PackageNotFound
...@@ -16,6 +14,7 @@ from poetry.repositories.link_sources.html import SimpleRepositoryPage ...@@ -16,6 +14,7 @@ from poetry.repositories.link_sources.html import SimpleRepositoryPage
if TYPE_CHECKING: if TYPE_CHECKING:
from packaging.utils import NormalizedName from packaging.utils import NormalizedName
from poetry.core.packages.utils.link import Link from poetry.core.packages.utils.link import Link
from poetry.core.semver.version import Version
from poetry.core.semver.version_constraint import VersionConstraint from poetry.core.semver.version_constraint import VersionConstraint
from poetry.config.config import Config from poetry.config.config import Config
...@@ -35,7 +34,7 @@ class LegacyRepository(HTTPRepository): ...@@ -35,7 +34,7 @@ class LegacyRepository(HTTPRepository):
super().__init__(name, url.rstrip("/"), config, disable_cache) super().__init__(name, url.rstrip("/"), config, disable_cache)
def package( def package(
self, name: str, version: str, extras: list[str] | None = None self, name: NormalizedName, version: Version, extras: list[str] | None = None
) -> Package: ) -> Package:
""" """
Retrieve the release information. Retrieve the release information.
...@@ -49,7 +48,7 @@ class LegacyRepository(HTTPRepository): ...@@ -49,7 +48,7 @@ class LegacyRepository(HTTPRepository):
should be much faster. should be much faster.
""" """
try: try:
index = self._packages.index(Package(name, version, version)) index = self._packages.index(Package(name, version))
return self._packages[index] return self._packages[index]
except ValueError: except ValueError:
...@@ -106,18 +105,20 @@ class LegacyRepository(HTTPRepository): ...@@ -106,18 +105,20 @@ class LegacyRepository(HTTPRepository):
for version in versions for version in versions
] ]
def _get_release_info(self, name: str, version: str) -> dict[str, Any]: def _get_release_info(
page = self._get_page(f"/{canonicalize_name(name)}/") self, name: NormalizedName, version: Version
) -> dict[str, Any]:
page = self._get_page(f"/{name}/")
if page is None: if page is None:
raise PackageNotFound(f'No package named "{name}"') raise PackageNotFound(f'No package named "{name}"')
links = list(page.links_for_version(name, Version.parse(version))) links = list(page.links_for_version(name, version))
return self._links_to_data( return self._links_to_data(
links, links,
PackageInfo( PackageInfo(
name=name, name=name,
version=version, version=version.text,
summary="", summary="",
platform=None, platform=None,
requires_dist=[], requires_dist=[],
......
...@@ -17,6 +17,7 @@ from poetry.utils.patterns import wheel_file_re ...@@ -17,6 +17,7 @@ from poetry.utils.patterns import wheel_file_re
if TYPE_CHECKING: if TYPE_CHECKING:
from collections.abc import Iterator from collections.abc import Iterator
from packaging.utils import NormalizedName
from poetry.core.packages.utils.link import Link from poetry.core.packages.utils.link import Link
...@@ -98,9 +99,9 @@ class LinkSource: ...@@ -98,9 +99,9 @@ class LinkSource:
pkg = Package(name, version, source_url=link.url) pkg = Package(name, version, source_url=link.url)
return pkg return pkg
def links_for_version(self, name: str, version: Version) -> Iterator[Link]: def links_for_version(
name = canonicalize_name(name) self, name: NormalizedName, version: Version
) -> Iterator[Link]:
for link in self.links: for link in self.links:
pkg = self.link_package_data(link) pkg = self.link_package_data(link)
......
...@@ -7,8 +7,10 @@ from poetry.repositories.repository import Repository ...@@ -7,8 +7,10 @@ from poetry.repositories.repository import Repository
if TYPE_CHECKING: if TYPE_CHECKING:
from packaging.utils import NormalizedName
from poetry.core.packages.dependency import Dependency from poetry.core.packages.dependency import Dependency
from poetry.core.packages.package import Package from poetry.core.packages.package import Package
from poetry.core.semver.version import Version
class Pool(Repository): class Pool(Repository):
...@@ -118,8 +120,8 @@ class Pool(Repository): ...@@ -118,8 +120,8 @@ class Pool(Repository):
def package( def package(
self, self,
name: str, name: NormalizedName,
version: str, version: Version,
extras: list[str] | None = None, extras: list[str] | None = None,
repository: str | None = None, repository: str | None = None,
) -> Package: ) -> Package:
......
...@@ -168,7 +168,7 @@ class PyPiRepository(HTTPRepository): ...@@ -168,7 +168,7 @@ class PyPiRepository(HTTPRepository):
return links return links
def _get_release_info( def _get_release_info(
self, name: str, version: str self, name: NormalizedName, version: Version
) -> dict[str, str | list[str] | None]: ) -> dict[str, str | list[str] | None]:
from poetry.inspection.info import PackageInfo from poetry.inspection.info import PackageInfo
......
...@@ -16,6 +16,7 @@ if TYPE_CHECKING: ...@@ -16,6 +16,7 @@ if TYPE_CHECKING:
from poetry.core.packages.dependency import Dependency from poetry.core.packages.dependency import Dependency
from poetry.core.packages.package import Package from poetry.core.packages.package import Package
from poetry.core.packages.utils.link import Link from poetry.core.packages.utils.link import Link
from poetry.core.semver.version import Version
class Repository: class Repository:
...@@ -133,12 +134,10 @@ class Repository: ...@@ -133,12 +134,10 @@ class Repository:
return [] return []
def package( def package(
self, name: str, version: str, extras: list[str] | None = None self, name: NormalizedName, version: Version, extras: list[str] | None = None
) -> Package: ) -> Package:
name = name.lower()
for package in self.packages: for package in self.packages:
if name == package.name and package.version.text == version: if name == package.name and package.version == version:
return package.clone() return package.clone()
raise PackageNotFound(f"Package {name} ({version}) not found.") raise PackageNotFound(f"Package {name} ({version}) not found.")
...@@ -72,7 +72,7 @@ def merge_dicts(d1: dict[str, Any], d2: dict[str, Any]) -> None: ...@@ -72,7 +72,7 @@ def merge_dicts(d1: dict[str, Any], d2: dict[str, Any]) -> None:
def download_file( def download_file(
url: str, url: str,
dest: str, dest: Path,
session: Authenticator | Session | None = None, session: Authenticator | Session | None = None,
chunk_size: int = 1024, chunk_size: int = 1024,
) -> None: ) -> None:
......
...@@ -125,13 +125,13 @@ def mock_clone( ...@@ -125,13 +125,13 @@ def mock_clone(
return MockDulwichRepo(dest) return MockDulwichRepo(dest)
def mock_download(url: str, dest: str, **__: Any) -> None: def mock_download(url: str, dest: Path) -> None:
parts = urllib.parse.urlparse(url) parts = urllib.parse.urlparse(url)
fixtures = Path(__file__).parent / "fixtures" fixtures = Path(__file__).parent / "fixtures"
fixture = fixtures / parts.path.lstrip("/") fixture = fixtures / parts.path.lstrip("/")
copy_or_symlink(fixture, Path(dest)) copy_or_symlink(fixture, dest)
class TestExecutor(Executor): class TestExecutor(Executor):
......
...@@ -12,6 +12,8 @@ import pytest ...@@ -12,6 +12,8 @@ import pytest
from cleo.io.null_io import NullIO from cleo.io.null_io import NullIO
from deepdiff import DeepDiff from deepdiff import DeepDiff
from packaging.utils import canonicalize_name
from poetry.core.semver.version import Version
from poetry.factory import Factory from poetry.factory import Factory
from poetry.masonry.builders.editable import EditableBuilder from poetry.masonry.builders.editable import EditableBuilder
...@@ -224,7 +226,7 @@ def test_builder_falls_back_on_setup_and_pip_for_packages_with_build_scripts( ...@@ -224,7 +226,7 @@ def test_builder_falls_back_on_setup_and_pip_for_packages_with_build_scripts(
assert [] == env.executed assert [] == env.executed
def test_builder_setup_generation_runs_with_pip_editable(tmp_dir: str): def test_builder_setup_generation_runs_with_pip_editable(tmp_dir: str) -> None:
# create an isolated copy of the project # create an isolated copy of the project
fixture = Path(__file__).parent.parent.parent / "fixtures" / "extended_project" fixture = Path(__file__).parent.parent.parent / "fixtures" / "extended_project"
extended_project = Path(tmp_dir) / "extended_project" extended_project = Path(tmp_dir) / "extended_project"
...@@ -241,7 +243,10 @@ def test_builder_setup_generation_runs_with_pip_editable(tmp_dir: str): ...@@ -241,7 +243,10 @@ def test_builder_setup_generation_runs_with_pip_editable(tmp_dir: str):
# is the package installed? # is the package installed?
repository = InstalledRepository.load(venv) repository = InstalledRepository.load(venv)
assert repository.package("extended-project", "1.2.3") package = repository.package(
canonicalize_name("extended-project"), Version.parse("1.2.3")
)
assert package.name == "extended-project"
# check for the module built by build.py # check for the module built by build.py
try: try:
......
...@@ -10,7 +10,9 @@ from typing import TYPE_CHECKING ...@@ -10,7 +10,9 @@ from typing import TYPE_CHECKING
import pytest import pytest
import requests import requests
from packaging.utils import canonicalize_name
from poetry.core.packages.dependency import Dependency from poetry.core.packages.dependency import Dependency
from poetry.core.semver.version import Version
from poetry.factory import Factory from poetry.factory import Factory
from poetry.repositories.exceptions import PackageNotFound from poetry.repositories.exceptions import PackageNotFound
...@@ -49,7 +51,7 @@ class MockRepository(LegacyRepository): ...@@ -49,7 +51,7 @@ class MockRepository(LegacyRepository):
fixture = self.FIXTURES / (name + ".html") fixture = self.FIXTURES / (name + ".html")
if not fixture.exists(): if not fixture.exists():
return return None
with fixture.open(encoding="utf-8") as f: with fixture.open(encoding="utf-8") as f:
return SimpleRepositoryPage(self._url + endpoint, f.read()) return SimpleRepositoryPage(self._url + endpoint, f.read())
...@@ -61,39 +63,43 @@ class MockRepository(LegacyRepository): ...@@ -61,39 +63,43 @@ class MockRepository(LegacyRepository):
shutil.copyfile(str(filepath), dest) shutil.copyfile(str(filepath), dest)
def test_page_relative_links_path_are_correct(): def test_page_relative_links_path_are_correct() -> None:
repo = MockRepository() repo = MockRepository()
page = repo._get_page("/relative") page = repo._get_page("/relative")
assert page is not None
for link in page.links: for link in page.links:
assert link.netloc == "legacy.foo.bar" assert link.netloc == "legacy.foo.bar"
assert link.path.startswith("/relative/poetry") assert link.path.startswith("/relative/poetry")
def test_page_absolute_links_path_are_correct(): def test_page_absolute_links_path_are_correct() -> None:
repo = MockRepository() repo = MockRepository()
page = repo._get_page("/absolute") page = repo._get_page("/absolute")
assert page is not None
for link in page.links: for link in page.links:
assert link.netloc == "files.pythonhosted.org" assert link.netloc == "files.pythonhosted.org"
assert link.path.startswith("/packages/") assert link.path.startswith("/packages/")
def test_page_clean_link(): def test_page_clean_link() -> None:
repo = MockRepository() repo = MockRepository()
page = repo._get_page("/relative") page = repo._get_page("/relative")
assert page is not None
cleaned = page.clean_link('https://legacy.foo.bar/test /the"/cleaning\0') cleaned = page.clean_link('https://legacy.foo.bar/test /the"/cleaning\0')
assert cleaned == "https://legacy.foo.bar/test%20/the%22/cleaning%00" assert cleaned == "https://legacy.foo.bar/test%20/the%22/cleaning%00"
def test_page_invalid_version_link(): def test_page_invalid_version_link() -> None:
repo = MockRepository() repo = MockRepository()
page = repo._get_page("/invalid-version") page = repo._get_page("/invalid-version")
assert page is not None
links = list(page.links) links = list(page.links)
assert len(links) == 2 assert len(links) == 2
...@@ -109,7 +115,7 @@ def test_page_invalid_version_link(): ...@@ -109,7 +115,7 @@ def test_page_invalid_version_link():
invalid_link = link invalid_link = link
break break
links_010 = list(page.links_for_version("poetry", versions[0])) links_010 = list(page.links_for_version(canonicalize_name("poetry"), versions[0]))
assert invalid_link not in links_010 assert invalid_link not in links_010
assert invalid_link assert invalid_link
...@@ -121,25 +127,28 @@ def test_page_invalid_version_link(): ...@@ -121,25 +127,28 @@ def test_page_invalid_version_link():
assert packages[0].version.to_string() == "0.1.0" assert packages[0].version.to_string() == "0.1.0"
def test_sdist_format_support(): def test_sdist_format_support() -> None:
repo = MockRepository() repo = MockRepository()
page = repo._get_page("/relative") page = repo._get_page("/relative")
assert page is not None
bz2_links = list(filter(lambda link: link.ext == ".tar.bz2", page.links)) bz2_links = list(filter(lambda link: link.ext == ".tar.bz2", page.links))
assert len(bz2_links) == 1 assert len(bz2_links) == 1
assert bz2_links[0].filename == "poetry-0.1.1.tar.bz2" assert bz2_links[0].filename == "poetry-0.1.1.tar.bz2"
def test_missing_version(): def test_missing_version() -> None:
repo = MockRepository() repo = MockRepository()
with pytest.raises(PackageNotFound): with pytest.raises(PackageNotFound):
repo._get_release_info("missing_version", "1.1.0") repo._get_release_info(
canonicalize_name("missing_version"), Version.parse("1.1.0")
)
def test_get_package_information_fallback_read_setup(): def test_get_package_information_fallback_read_setup() -> None:
repo = MockRepository() repo = MockRepository()
package = repo.package("jupyter", "1.0.0") package = repo.package(canonicalize_name("jupyter"), Version.parse("1.0.0"))
assert package.source_type == "legacy" assert package.source_type == "legacy"
assert package.source_reference == repo.name assert package.source_reference == repo.name
...@@ -152,10 +161,12 @@ def test_get_package_information_fallback_read_setup(): ...@@ -152,10 +161,12 @@ def test_get_package_information_fallback_read_setup():
) )
def test_get_package_information_skips_dependencies_with_invalid_constraints(): def test_get_package_information_skips_dependencies_with_invalid_constraints() -> None:
repo = MockRepository() repo = MockRepository()
package = repo.package("python-language-server", "0.21.2") package = repo.package(
canonicalize_name("python-language-server"), Version.parse("0.21.2")
)
assert package.name == "python-language-server" assert package.name == "python-language-server"
assert package.version.text == "0.21.2" assert package.version.text == "0.21.2"
...@@ -188,7 +199,7 @@ def test_get_package_information_skips_dependencies_with_invalid_constraints(): ...@@ -188,7 +199,7 @@ def test_get_package_information_skips_dependencies_with_invalid_constraints():
] ]
def test_find_packages_no_prereleases(): def test_find_packages_no_prereleases() -> None:
repo = MockRepository() repo = MockRepository()
packages = repo.find_packages(Factory.create_dependency("pyyaml", "*")) packages = repo.find_packages(Factory.create_dependency("pyyaml", "*"))
...@@ -203,7 +214,7 @@ def test_find_packages_no_prereleases(): ...@@ -203,7 +214,7 @@ def test_find_packages_no_prereleases():
@pytest.mark.parametrize( @pytest.mark.parametrize(
["constraint", "count"], [("*", 1), (">=1", 0), (">=19.0.0a0", 1)] ["constraint", "count"], [("*", 1), (">=1", 0), (">=19.0.0a0", 1)]
) )
def test_find_packages_only_prereleases(constraint: str, count: int): def test_find_packages_only_prereleases(constraint: str, count: int) -> None:
repo = MockRepository() repo = MockRepository()
packages = repo.find_packages(Factory.create_dependency("black", constraint)) packages = repo.find_packages(Factory.create_dependency("black", constraint))
...@@ -216,17 +227,17 @@ def test_find_packages_only_prereleases(constraint: str, count: int): ...@@ -216,17 +227,17 @@ def test_find_packages_only_prereleases(constraint: str, count: int):
assert package.source_url == repo.url assert package.source_url == repo.url
def test_find_packages_only_prereleases_empty_when_not_any(): def test_find_packages_only_prereleases_empty_when_not_any() -> None:
repo = MockRepository() repo = MockRepository()
packages = repo.find_packages(Factory.create_dependency("black", ">=1")) packages = repo.find_packages(Factory.create_dependency("black", ">=1"))
assert len(packages) == 0 assert len(packages) == 0
def test_get_package_information_chooses_correct_distribution(): def test_get_package_information_chooses_correct_distribution() -> None:
repo = MockRepository() repo = MockRepository()
package = repo.package("isort", "4.3.4") package = repo.package(canonicalize_name("isort"), Version.parse("4.3.4"))
assert package.name == "isort" assert package.name == "isort"
assert package.version.text == "4.3.4" assert package.version.text == "4.3.4"
...@@ -236,30 +247,32 @@ def test_get_package_information_chooses_correct_distribution(): ...@@ -236,30 +247,32 @@ def test_get_package_information_chooses_correct_distribution():
assert futures_dep.python_versions == "~2.7" assert futures_dep.python_versions == "~2.7"
def test_get_package_information_includes_python_requires(): def test_get_package_information_includes_python_requires() -> None:
repo = MockRepository() repo = MockRepository()
package = repo.package("futures", "3.2.0") package = repo.package(canonicalize_name("futures"), Version.parse("3.2.0"))
assert package.name == "futures" assert package.name == "futures"
assert package.version.text == "3.2.0" assert package.version.text == "3.2.0"
assert package.python_versions == ">=2.6, <3" assert package.python_versions == ">=2.6, <3"
def test_get_package_information_sets_appropriate_python_versions_if_wheels_only(): def test_get_package_information_sets_appropriate_python_versions_if_wheels_only() -> (
None
):
repo = MockRepository() repo = MockRepository()
package = repo.package("futures", "3.2.0") package = repo.package(canonicalize_name("futures"), Version.parse("3.2.0"))
assert package.name == "futures" assert package.name == "futures"
assert package.version.text == "3.2.0" assert package.version.text == "3.2.0"
assert package.python_versions == ">=2.6, <3" assert package.python_versions == ">=2.6, <3"
def test_get_package_from_both_py2_and_py3_specific_wheels(): def test_get_package_from_both_py2_and_py3_specific_wheels() -> None:
repo = MockRepository() repo = MockRepository()
package = repo.package("ipython", "5.7.0") package = repo.package(canonicalize_name("ipython"), Version.parse("5.7.0"))
assert package.name == "ipython" assert package.name == "ipython"
assert package.version.text == "5.7.0" assert package.version.text == "5.7.0"
...@@ -294,20 +307,22 @@ def test_get_package_from_both_py2_and_py3_specific_wheels(): ...@@ -294,20 +307,22 @@ def test_get_package_from_both_py2_and_py3_specific_wheels():
assert str(required[5].marker) == 'sys_platform != "win32"' assert str(required[5].marker) == 'sys_platform != "win32"'
def test_get_package_from_both_py2_and_py3_specific_wheels_python_constraint(): def test_get_package_from_both_py2_and_py3_specific_wheels_python_constraint() -> None:
repo = MockRepository() repo = MockRepository()
package = repo.package("poetry-test-py2-py3-metadata-merge", "0.1.0") package = repo.package(
canonicalize_name("poetry-test-py2-py3-metadata-merge"), Version.parse("0.1.0")
)
assert package.name == "poetry-test-py2-py3-metadata-merge" assert package.name == "poetry-test-py2-py3-metadata-merge"
assert package.version.text == "0.1.0" assert package.version.text == "0.1.0"
assert package.python_versions == ">=2.7,<2.8 || >=3.7,<4.0" assert package.python_versions == ">=2.7,<2.8 || >=3.7,<4.0"
def test_get_package_with_dist_and_universal_py3_wheel(): def test_get_package_with_dist_and_universal_py3_wheel() -> None:
repo = MockRepository() repo = MockRepository()
package = repo.package("ipython", "7.5.0") package = repo.package(canonicalize_name("ipython"), Version.parse("7.5.0"))
assert package.name == "ipython" assert package.name == "ipython"
assert package.version.text == "7.5.0" assert package.version.text == "7.5.0"
...@@ -332,10 +347,10 @@ def test_get_package_with_dist_and_universal_py3_wheel(): ...@@ -332,10 +347,10 @@ def test_get_package_with_dist_and_universal_py3_wheel():
assert sorted(required, key=lambda dep: dep.name) == expected assert sorted(required, key=lambda dep: dep.name) == expected
def test_get_package_retrieves_non_sha256_hashes(): def test_get_package_retrieves_non_sha256_hashes() -> None:
repo = MockRepository() repo = MockRepository()
package = repo.package("ipython", "7.5.0") package = repo.package(canonicalize_name("ipython"), Version.parse("7.5.0"))
expected = [ expected = [
{ {
...@@ -351,10 +366,10 @@ def test_get_package_retrieves_non_sha256_hashes(): ...@@ -351,10 +366,10 @@ def test_get_package_retrieves_non_sha256_hashes():
assert package.files == expected assert package.files == expected
def test_get_package_retrieves_non_sha256_hashes_mismatching_known_hash(): def test_get_package_retrieves_non_sha256_hashes_mismatching_known_hash() -> None:
repo = MockRepository() repo = MockRepository()
package = repo.package("ipython", "5.7.0") package = repo.package(canonicalize_name("ipython"), Version.parse("5.7.0"))
expected = [ expected = [
{ {
...@@ -374,10 +389,10 @@ def test_get_package_retrieves_non_sha256_hashes_mismatching_known_hash(): ...@@ -374,10 +389,10 @@ def test_get_package_retrieves_non_sha256_hashes_mismatching_known_hash():
assert package.files == expected assert package.files == expected
def test_get_package_retrieves_packages_with_no_hashes(): def test_get_package_retrieves_packages_with_no_hashes() -> None:
repo = MockRepository() repo = MockRepository()
package = repo.package("jupyter", "1.0.0") package = repo.package(canonicalize_name("jupyter"), Version.parse("1.0.0"))
assert [ assert [
{ {
...@@ -399,20 +414,22 @@ class MockHttpRepository(LegacyRepository): ...@@ -399,20 +414,22 @@ class MockHttpRepository(LegacyRepository):
http.register_uri(http.GET, url, status=response) http.register_uri(http.GET, url, status=response)
def test_get_200_returns_page(http: type[httpretty.httpretty]): def test_get_200_returns_page(http: type[httpretty.httpretty]) -> None:
repo = MockHttpRepository({"/foo": 200}, http) repo = MockHttpRepository({"/foo": 200}, http)
assert repo._get_page("/foo") assert repo._get_page("/foo")
@pytest.mark.parametrize("status_code", [401, 403, 404]) @pytest.mark.parametrize("status_code", [401, 403, 404])
def test_get_40x_and_returns_none(http: type[httpretty.httpretty], status_code: int): def test_get_40x_and_returns_none(
http: type[httpretty.httpretty], status_code: int
) -> None:
repo = MockHttpRepository({"/foo": status_code}, http) repo = MockHttpRepository({"/foo": status_code}, http)
assert repo._get_page("/foo") is None assert repo._get_page("/foo") is None
def test_get_5xx_raises(http: type[httpretty.httpretty]): def test_get_5xx_raises(http: type[httpretty.httpretty]) -> None:
repo = MockHttpRepository({"/foo": 500}, http) repo = MockHttpRepository({"/foo": 500}, http)
with pytest.raises(RepositoryError): with pytest.raises(RepositoryError):
...@@ -421,7 +438,7 @@ def test_get_5xx_raises(http: type[httpretty.httpretty]): ...@@ -421,7 +438,7 @@ def test_get_5xx_raises(http: type[httpretty.httpretty]):
def test_get_redirected_response_url( def test_get_redirected_response_url(
http: type[httpretty.httpretty], monkeypatch: MonkeyPatch http: type[httpretty.httpretty], monkeypatch: MonkeyPatch
): ) -> None:
repo = MockHttpRepository({"/foo": 200}, http) repo = MockHttpRepository({"/foo": 200}, http)
redirect_url = "http://legacy.redirect.bar" redirect_url = "http://legacy.redirect.bar"
...@@ -434,7 +451,9 @@ def test_get_redirected_response_url( ...@@ -434,7 +451,9 @@ def test_get_redirected_response_url(
return response return response
monkeypatch.setattr(repo.session, "get", get_mock) monkeypatch.setattr(repo.session, "get", get_mock)
assert repo._get_page("/foo")._url == "http://legacy.redirect.bar/foo/" page = repo._get_page("/foo")
assert page is not None
assert page._url == "http://legacy.redirect.bar/foo/"
@pytest.mark.parametrize( @pytest.mark.parametrize(
......
...@@ -2,18 +2,21 @@ from __future__ import annotations ...@@ -2,18 +2,21 @@ from __future__ import annotations
import pytest import pytest
from packaging.utils import canonicalize_name
from poetry.core.semver.version import Version
from poetry.repositories import Pool from poetry.repositories import Pool
from poetry.repositories import Repository from poetry.repositories import Repository
from poetry.repositories.exceptions import PackageNotFound from poetry.repositories.exceptions import PackageNotFound
from poetry.repositories.legacy_repository import LegacyRepository from poetry.repositories.legacy_repository import LegacyRepository
def test_pool_raises_package_not_found_when_no_package_is_found(): def test_pool_raises_package_not_found_when_no_package_is_found() -> None:
pool = Pool() pool = Pool()
pool.add_repository(Repository("repo")) pool.add_repository(Repository("repo"))
with pytest.raises(PackageNotFound): with pytest.raises(PackageNotFound):
pool.package("foo", "1.0.0") pool.package(canonicalize_name("foo"), Version.parse("1.0.0"))
def test_pool(): def test_pool():
......
...@@ -9,7 +9,9 @@ from typing import TYPE_CHECKING ...@@ -9,7 +9,9 @@ from typing import TYPE_CHECKING
import pytest import pytest
from packaging.utils import canonicalize_name
from poetry.core.packages.dependency import Dependency from poetry.core.packages.dependency import Dependency
from poetry.core.semver.version import Version
from requests.exceptions import TooManyRedirects from requests.exceptions import TooManyRedirects
from requests.models import Response from requests.models import Response
...@@ -50,7 +52,7 @@ class MockRepository(PyPiRepository): ...@@ -50,7 +52,7 @@ class MockRepository(PyPiRepository):
fixture = self.JSON_FIXTURES / (name + ".json") fixture = self.JSON_FIXTURES / (name + ".json")
if not fixture.exists(): if not fixture.exists():
return return None
with fixture.open(encoding="utf-8") as f: with fixture.open(encoding="utf-8") as f:
return json.loads(f.read()) return json.loads(f.read())
...@@ -63,21 +65,21 @@ class MockRepository(PyPiRepository): ...@@ -63,21 +65,21 @@ class MockRepository(PyPiRepository):
shutil.copyfile(str(fixture), dest) shutil.copyfile(str(fixture), dest)
def test_find_packages(): def test_find_packages() -> None:
repo = MockRepository() repo = MockRepository()
packages = repo.find_packages(Factory.create_dependency("requests", "^2.18")) packages = repo.find_packages(Factory.create_dependency("requests", "^2.18"))
assert len(packages) == 5 assert len(packages) == 5
def test_find_packages_with_prereleases(): def test_find_packages_with_prereleases() -> None:
repo = MockRepository() repo = MockRepository()
packages = repo.find_packages(Factory.create_dependency("toga", ">=0.3.0.dev2")) packages = repo.find_packages(Factory.create_dependency("toga", ">=0.3.0.dev2"))
assert len(packages) == 7 assert len(packages) == 7
def test_find_packages_does_not_select_prereleases_if_not_allowed(): def test_find_packages_does_not_select_prereleases_if_not_allowed() -> None:
repo = MockRepository() repo = MockRepository()
packages = repo.find_packages(Factory.create_dependency("pyyaml", "*")) packages = repo.find_packages(Factory.create_dependency("pyyaml", "*"))
...@@ -87,17 +89,17 @@ def test_find_packages_does_not_select_prereleases_if_not_allowed(): ...@@ -87,17 +89,17 @@ def test_find_packages_does_not_select_prereleases_if_not_allowed():
@pytest.mark.parametrize( @pytest.mark.parametrize(
["constraint", "count"], [("*", 1), (">=1", 0), (">=19.0.0a0", 1)] ["constraint", "count"], [("*", 1), (">=1", 0), (">=19.0.0a0", 1)]
) )
def test_find_packages_only_prereleases(constraint: str, count: int): def test_find_packages_only_prereleases(constraint: str, count: int) -> None:
repo = MockRepository() repo = MockRepository()
packages = repo.find_packages(Factory.create_dependency("black", constraint)) packages = repo.find_packages(Factory.create_dependency("black", constraint))
assert len(packages) == count assert len(packages) == count
def test_package(): def test_package() -> None:
repo = MockRepository() repo = MockRepository()
package = repo.package("requests", "2.18.4") package = repo.package(canonicalize_name("requests"), Version.parse("2.18.4"))
assert package.name == "requests" assert package.name == "requests"
assert len(package.requires) == 9 assert len(package.requires) == 9
...@@ -126,10 +128,10 @@ def test_package(): ...@@ -126,10 +128,10 @@ def test_package():
) )
def test_fallback_on_downloading_packages(): def test_fallback_on_downloading_packages() -> None:
repo = MockRepository(fallback=True) repo = MockRepository(fallback=True)
package = repo.package("jupyter", "1.0.0") package = repo.package(canonicalize_name("jupyter"), Version.parse("1.0.0"))
assert package.name == "jupyter" assert package.name == "jupyter"
assert len(package.requires) == 6 assert len(package.requires) == 6
...@@ -145,10 +147,10 @@ def test_fallback_on_downloading_packages(): ...@@ -145,10 +147,10 @@ def test_fallback_on_downloading_packages():
] ]
def test_fallback_inspects_sdist_first_if_no_matching_wheels_can_be_found(): def test_fallback_inspects_sdist_first_if_no_matching_wheels_can_be_found() -> None:
repo = MockRepository(fallback=True) repo = MockRepository(fallback=True)
package = repo.package("isort", "4.3.4") package = repo.package(canonicalize_name("isort"), Version.parse("4.3.4"))
assert package.name == "isort" assert package.name == "isort"
assert len(package.requires) == 1 assert len(package.requires) == 1
...@@ -158,10 +160,10 @@ def test_fallback_inspects_sdist_first_if_no_matching_wheels_can_be_found(): ...@@ -158,10 +160,10 @@ def test_fallback_inspects_sdist_first_if_no_matching_wheels_can_be_found():
assert dep.python_versions == "~2.7" assert dep.python_versions == "~2.7"
def test_fallback_can_read_setup_to_get_dependencies(): def test_fallback_can_read_setup_to_get_dependencies() -> None:
repo = MockRepository(fallback=True) repo = MockRepository(fallback=True)
package = repo.package("sqlalchemy", "1.2.12") package = repo.package(canonicalize_name("sqlalchemy"), Version.parse("1.2.12"))
assert package.name == "sqlalchemy" assert package.name == "sqlalchemy"
assert len(package.requires) == 9 assert len(package.requires) == 9
...@@ -180,10 +182,10 @@ def test_fallback_can_read_setup_to_get_dependencies(): ...@@ -180,10 +182,10 @@ def test_fallback_can_read_setup_to_get_dependencies():
} }
def test_pypi_repository_supports_reading_bz2_files(): def test_pypi_repository_supports_reading_bz2_files() -> None:
repo = MockRepository(fallback=True) repo = MockRepository(fallback=True)
package = repo.package("twisted", "18.9.0") package = repo.package(canonicalize_name("twisted"), Version.parse("18.9.0"))
assert package.name == "twisted" assert package.name == "twisted"
assert len(package.requires) == 71 assert len(package.requires) == 71
...@@ -220,7 +222,7 @@ def test_pypi_repository_supports_reading_bz2_files(): ...@@ -220,7 +222,7 @@ def test_pypi_repository_supports_reading_bz2_files():
) )
def test_invalid_versions_ignored(): def test_invalid_versions_ignored() -> None:
repo = MockRepository() repo = MockRepository()
# the json metadata for this package contains one malformed version # the json metadata for this package contains one malformed version
...@@ -229,7 +231,9 @@ def test_invalid_versions_ignored(): ...@@ -229,7 +231,9 @@ def test_invalid_versions_ignored():
assert len(packages) == 1 assert len(packages) == 1
def test_get_should_invalid_cache_on_too_many_redirects_error(mocker: MockerFixture): def test_get_should_invalid_cache_on_too_many_redirects_error(
mocker: MockerFixture,
) -> None:
delete_cache = mocker.patch("cachecontrol.caches.file_cache.FileCache.delete") delete_cache = mocker.patch("cachecontrol.caches.file_cache.FileCache.delete")
response = Response() response = Response()
...@@ -246,14 +250,14 @@ def test_get_should_invalid_cache_on_too_many_redirects_error(mocker: MockerFixt ...@@ -246,14 +250,14 @@ def test_get_should_invalid_cache_on_too_many_redirects_error(mocker: MockerFixt
assert delete_cache.called assert delete_cache.called
def test_urls(): def test_urls() -> None:
repository = PyPiRepository() repository = PyPiRepository()
assert repository.url == "https://pypi.org/simple/" assert repository.url == "https://pypi.org/simple/"
assert repository.authenticated_url == "https://pypi.org/simple/" assert repository.authenticated_url == "https://pypi.org/simple/"
def test_use_pypi_pretty_name(): def test_use_pypi_pretty_name() -> None:
repo = MockRepository(fallback=True) repo = MockRepository(fallback=True)
package = repo.find_packages(Factory.create_dependency("twisted", "*")) package = repo.find_packages(Factory.create_dependency("twisted", "*"))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment