Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

draft: test fixture rework for dropping json API for PyPI #9186

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions src/poetry/repositories/http_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@

if TYPE_CHECKING:
from packaging.utils import NormalizedName
from poetry.core.constraints.version import Version
from poetry.core.packages.package import Package
from poetry.core.packages.utils.link import Link

from poetry.repositories.link_sources.base import LinkSource
Expand Down Expand Up @@ -91,6 +93,36 @@ def certificates(self) -> RepositoryCertificateConfig:
def authenticated_url(self) -> str:
return self._authenticator.authenticated_url(url=self.url)

def find_links_for_package(self, package: Package) -> list[Link]:
try:
page = self.get_page(package.name)
except PackageNotFound:
return []

return list(page.links_for_version(package.name, package.version))

def _get_release_info(
self, name: NormalizedName, version: Version
) -> dict[str, Any]:
page = self.get_page(name)

links = list(page.links_for_version(name, version))
yanked = page.yanked(name, version)

return self._links_to_data(
links,
PackageInfo(
name=name,
version=version.text,
summary="",
requires_dist=[],
requires_python=None,
files=[],
yanked=yanked,
cache_version=str(self.CACHE_VERSION),
),
)

def _download(
self, url: str, dest: Path, *, raise_accepts_ranges: bool = False
) -> None:
Expand Down
33 changes: 0 additions & 33 deletions src/poetry/repositories/legacy_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@
from contextlib import suppress
from functools import cached_property
from typing import TYPE_CHECKING
from typing import Any

import requests.adapters

from poetry.core.packages.package import Package

from poetry.inspection.info import PackageInfo
from poetry.repositories.exceptions import PackageNotFound
from poetry.repositories.http_repository import HTTPRepository
from poetry.repositories.link_sources.html import SimpleRepositoryPage
Expand All @@ -20,7 +18,6 @@
from packaging.utils import NormalizedName
from poetry.core.constraints.version import Version
from poetry.core.constraints.version import VersionConstraint
from poetry.core.packages.utils.link import Link

from poetry.config.config import Config

Expand Down Expand Up @@ -65,14 +62,6 @@ def package(

return package

def find_links_for_package(self, package: Package) -> list[Link]:
try:
page = self.get_page(package.name)
except PackageNotFound:
return []

return list(page.links_for_version(package.name, package.version))

def _find_packages(
self, name: NormalizedName, constraint: VersionConstraint
) -> list[Package]:
Expand Down Expand Up @@ -103,28 +92,6 @@ def _find_packages(
for version, yanked in versions
]

def _get_release_info(
self, name: NormalizedName, version: Version
) -> dict[str, Any]:
page = self.get_page(name)

links = list(page.links_for_version(name, version))
yanked = page.yanked(name, version)

return self._links_to_data(
links,
PackageInfo(
name=name,
version=version.text,
summary="",
requires_dist=[],
requires_python=None,
files=[],
yanked=yanked,
cache_version=str(self.CACHE_VERSION),
),
)

def _get_page(self, name: NormalizedName) -> SimpleRepositoryPage:
if not (response := self._get_response(f"/{name}/")):
raise PackageNotFound(f"Package [{name}] not found.")
Expand Down
7 changes: 6 additions & 1 deletion src/poetry/repositories/link_sources/json.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,13 @@ def _link_cache(self) -> LinkCache:
metadata = bool(metadata_value)
break

hashes = file.get("hashes")
link = Link(
url, requires_python=requires_python, yanked=yanked, metadata=metadata
url,
requires_python=requires_python,
hashes=hashes,
yanked=yanked,
metadata=metadata,
)

if link.ext not in self.SUPPORTED_FORMATS:
Expand Down
79 changes: 0 additions & 79 deletions src/poetry/repositories/pypi_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

from cachecontrol.controller import logger as cache_control_logger
from poetry.core.packages.package import Package
from poetry.core.packages.utils.link import Link
from poetry.core.version.exceptions import InvalidVersion

from poetry.repositories.exceptions import PackageNotFound
Expand All @@ -26,18 +25,14 @@

if TYPE_CHECKING:
from packaging.utils import NormalizedName
from poetry.core.constraints.version import Version
from poetry.core.constraints.version import VersionConstraint

SUPPORTED_PACKAGE_TYPES = {"sdist", "bdist_wheel"}


class PyPiRepository(HTTPRepository):
def __init__(
self,
url: str = "https://pypi.org/",
disable_cache: bool = False,
fallback: bool = True,
pool_size: int = requests.adapters.DEFAULT_POOLSIZE,
) -> None:
super().__init__(
Expand All @@ -48,7 +43,6 @@ def __init__(
)

self._base_url = url
self._fallback = fallback

def search(self, query: str) -> list[Package]:
results = []
Expand Down Expand Up @@ -110,79 +104,6 @@ def _get_package_info(self, name: NormalizedName) -> dict[str, Any]:

return info

def find_links_for_package(self, package: Package) -> list[Link]:
json_data = self._get(f"pypi/{package.name}/{package.version}/json")
if json_data is None:
return []

links = []
for url in json_data["urls"]:
if url["packagetype"] in SUPPORTED_PACKAGE_TYPES:
h = f"sha256={url['digests']['sha256']}"
links.append(Link(url["url"] + "#" + h, yanked=self._get_yanked(url)))

return links

def _get_release_info(
self, name: NormalizedName, version: Version
) -> dict[str, Any]:
from poetry.inspection.info import PackageInfo

self._log(f"Getting info for {name} ({version}) from PyPI", "debug")

json_data = self._get(f"pypi/{name}/{version}/json")
if json_data is None:
raise PackageNotFound(f"Package [{name}] not found.")

info = json_data["info"]

data = PackageInfo(
name=info["name"],
version=info["version"],
summary=info["summary"],
requires_dist=info["requires_dist"],
requires_python=info["requires_python"],
yanked=self._get_yanked(info),
cache_version=str(self.CACHE_VERSION),
)

try:
version_info = json_data["urls"]
except KeyError:
version_info = []

files = info.get("files", [])
for file_info in version_info:
if file_info["packagetype"] in SUPPORTED_PACKAGE_TYPES:
files.append(
{
"file": file_info["filename"],
"hash": "sha256:" + file_info["digests"]["sha256"],
}
)
data.files = files

if self._fallback and data.requires_dist is None:
self._log(
"No dependencies found, downloading metadata and/or archives",
level="debug",
)
# No dependencies set (along with other information)
# This might be due to actually no dependencies
# or badly set metadata when uploading.
# So, we need to make sure there is actually no
# dependencies by introspecting packages.
page = self.get_page(name)
links = list(page.links_for_version(name, version))
info = self._get_info_from_links(links)

data.requires_dist = info.requires_dist

if not data.requires_python:
data.requires_python = info.requires_python

return data.asdict()

def _get_page(self, name: NormalizedName) -> SimpleJsonPage:
source = self._base_url + f"simple/{name}/"
info = self.get_package_info(name)
Expand Down
4 changes: 3 additions & 1 deletion tests/installation/fixtures/with-pypi-repository.test
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,10 @@ name = "pluggy"
version = "0.6.0"
description = "plugin and hook calling mechanisms for python"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
python-versions = ">=2.7,<3.0.dev0 || >=3.4.dev0"
files = [
{file = "pluggy-0.6.0-py2-none-any.whl", hash = "sha256:9b835f86bfe5498c87ace7f4899cb1b0c40e71c9277377f6851c74a307879285"},
{file = "pluggy-0.6.0-py3-none-any.whl", hash = "sha256:8c646771f5eab7557d1f3924077c55408e86bdfb700f7d86a6d83abeabff4c66"},
{file = "pluggy-0.6.0.tar.gz", hash = "sha256:a982e208d054867661d27c6d2a86b17ba05fbb6b1bdc01f42660732dd107f865"},
]

Expand Down
1 change: 0 additions & 1 deletion tests/installation/test_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@ def io_not_decorated() -> BufferedIO:
def pool(pypi_repository: PyPiRepository) -> RepositoryPool:
pool = RepositoryPool()

pypi_repository._fallback = True
pool.add_repository(pypi_repository)

return pool
Expand Down
8 changes: 6 additions & 2 deletions tests/installation/test_installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -1916,7 +1916,11 @@ def test_installer_required_extras_should_not_be_removed_when_updating_single_de
executor=Executor(env, pool, config, NullIO()),
)

package.add_dependency(Factory.create_dependency("poetry", {"version": "^0.12.0"}))
package.add_dependency(
Factory.create_dependency(
"with-transitive-extra-dependency", {"version": "^0.12"}
)
)

installer.update(True)
result = installer.run()
Expand Down Expand Up @@ -1979,7 +1983,7 @@ def test_installer_required_extras_should_be_installed(
)
package.add_dependency(
Factory.create_dependency(
"cachecontrol", {"version": "^0.12.5", "extras": ["filecache"]}
"with-extra-dependency", {"version": "^0.12", "extras": ["filecache"]}
)
)

Expand Down
7 changes: 4 additions & 3 deletions tests/puzzle/test_solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -3019,18 +3019,19 @@ def test_solver_can_solve_with_legacy_repository_using_proper_python_compatible_
def test_solver_skips_invalid_versions(
package: ProjectPackage, io: NullIO, pypi_repository: PyPiRepository
) -> None:
package.python_versions = "^3.7"
package.python_versions = "^3.9"

pool = RepositoryPool([pypi_repository])

solver = Solver(package, pool, [], [], io)

package.add_dependency(Factory.create_dependency("trackpy", "^0.4"))
package.add_dependency(Factory.create_dependency("six-unknown-version", "^1.11"))

transaction = solver.solve()

check_solver_result(
transaction, [{"job": "install", "package": get_package("trackpy", "0.4.1")}]
transaction,
[{"job": "install", "package": get_package("six-unknown-version", "1.11.0")}],
)


Expand Down
4 changes: 4 additions & 0 deletions tests/repositories/fixtures/distribution_hashes.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ class DistributionHash:
"baf0d469c9e541b747986b7404cd63a5496955bd0c43a3cc068c449b09b7d4a4",
"40eb168dab84e606df3fdb7e67fe27b7",
),
"hbmqtt-0.9.6.tar.gz": DistributionHash(
"379f1d9044997c69308ac2e01621c817b5394e1fbe0696e62538ae2dd0aa7e07",
"b284e3118882f169aa618a856cd91c5f",
),
"ipython-5.7.0-py2-none-any.whl": DistributionHash(
"3d93d3995e2e52a98dc4f44361cd5bf68dbde62925d1f820b97d8f0e1d941f73",
"cf35939995e0fd8c44fca7509308abde",
Expand Down
Binary file not shown.
Loading
Loading