link_sources: fix parsing of non-wheel non-sdist links

This commit is contained in:
Randy Döring 2022-05-06 06:49:03 +02:00 committed by Arun Babu Neelicattu
parent cd3026f792
commit 0d418fc00e
3 changed files with 109 additions and 14 deletions
src/poetry/repositories/link_sources
tests/repositories/link_sources

View File

@ -49,7 +49,7 @@ class LinkSource:
for link in self.links:
pkg = self.link_package_data(link)
if pkg and pkg.name == name and pkg.version and pkg.version not in seen:
if pkg and pkg.name == name and pkg.version not in seen:
seen.add(pkg.version)
yield pkg.version
@ -58,7 +58,7 @@ class LinkSource:
for link in self.links:
pkg = self.link_package_data(link)
if pkg and pkg.name and pkg.version:
if pkg:
yield pkg
@property
@ -66,8 +66,9 @@ class LinkSource:
def links(self) -> Iterator[Link]:
raise NotImplementedError()
def link_package_data(self, link: Link) -> Package | None:
name, version = None, None
@classmethod
def link_package_data(cls, link: Link) -> Package | None:
name, version_string, version = None, None, None
m = wheel_file_re.match(link.filename) or sdist_file_re.match(link.filename)
if m:
@ -75,19 +76,24 @@ class LinkSource:
version_string = m.group("ver")
else:
info, ext = link.splitext()
match = self.VERSION_REGEX.match(info)
match = cls.VERSION_REGEX.match(info)
if match:
name = match.group(1)
version_string = match.group(2)
try:
version = Version.parse(version_string)
except ValueError:
logger.debug(
"Skipping url (%s) due to invalid version (%s)", link.url, version
)
return None
if version_string:
try:
version = Version.parse(version_string)
except ValueError:
logger.debug(
"Skipping url (%s) due to invalid version (%s)", link.url, version
)
return None
return Package(name, version, source_url=link.url)
pkg = None
if name and version:
pkg = Package(name, version, source_url=link.url)
return pkg
def links_for_version(self, name: str, version: Version) -> Iterator[Link]:
name = canonicalize_name(name)
@ -95,7 +101,7 @@ class LinkSource:
for link in self.links:
pkg = self.link_package_data(link)
if pkg and pkg.name == name and pkg.version and pkg.version == version:
if pkg and pkg.name == name and pkg.version == version:
yield link
def clean_link(self, url: str) -> str:

View File

@ -0,0 +1,89 @@
from __future__ import annotations
from typing import TYPE_CHECKING
from typing import Iterable
from unittest.mock import PropertyMock
import pytest
from poetry.core.packages.package import Package
from poetry.core.packages.utils.link import Link
from poetry.core.semver.version import Version
from poetry.repositories.link_sources.base import LinkSource
if TYPE_CHECKING:
from pytest_mock import MockerFixture
@pytest.fixture
def link_source(mocker: MockerFixture) -> LinkSource:
url = "https://example.org"
link_source = LinkSource(url)
mocker.patch(
f"{LinkSource.__module__}.{LinkSource.__qualname__}.links",
new_callable=PropertyMock,
return_value=iter(
[
Link(f"{url}/demo-0.1.0.tar.gz"),
Link(f"{url}/demo-0.1.0_invalid.tar.gz"),
Link(f"{url}/invalid.tar.gz"),
Link(f"{url}/demo-0.1.0-py2.py3-none-any.whl"),
Link(f"{url}/demo-0.1.1.tar.gz"),
]
),
)
return link_source
@pytest.mark.parametrize(
"filename, expected",
[
("demo-0.1.0-py2.py3-none-any.whl", Package("demo", "0.1.0")),
("demo-0.1.0.tar.gz", Package("demo", "0.1.0")),
("demo-0.1.0.egg", Package("demo", "0.1.0")),
("demo-0.1.0_invalid-py2.py3-none-any.whl", None), # invalid version
("demo-0.1.0_invalid.egg", None), # invalid version
("no-package-at-all.txt", None),
],
)
def test_link_package_data(filename: str, expected: Package | None) -> None:
link = Link(f"https://example.org/{filename}")
assert LinkSource.link_package_data(link) == expected
@pytest.mark.parametrize(
"name, expected",
[
("demo", {Version.parse("0.1.0"), Version.parse("0.1.1")}),
("invalid", set()),
],
)
def test_versions(name: str, expected: set[Version], link_source: LinkSource) -> None:
assert set(link_source.versions(name)) == expected
def test_packages(link_source: LinkSource) -> None:
expected = {
Package("demo", "0.1.0"),
Package("demo", "0.1.0"),
Package("demo", "0.1.1"),
}
assert set(link_source.packages) == expected
@pytest.mark.parametrize(
"version_string, filenames",
[
("0.1.0", ["demo-0.1.0.tar.gz", "demo-0.1.0-py2.py3-none-any.whl"]),
("0.1.1", ["demo-0.1.1.tar.gz"]),
("0.1.2", []),
],
)
def test_links_for_version(
version_string: str, filenames: Iterable[str], link_source: LinkSource
) -> None:
version = Version.parse(version_string)
expected = {Link(f"{link_source.url}/{name}") for name in filenames}
assert set(link_source.links_for_version("demo", version)) == expected