Skip to content

Commit

Permalink
Handle (*) constraint for pre-release only packages
Browse files Browse the repository at this point in the history
This change ensures that packages that only have a pre-release versions
are pragmatically discovered via `find_packages` when a constraint (*)
is specified.

Resolves: #2819
  • Loading branch information
abn committed Aug 17, 2020
1 parent 0d48fb6 commit a357650
Show file tree
Hide file tree
Showing 8 changed files with 220 additions and 14 deletions.
36 changes: 24 additions & 12 deletions poetry/repositories/legacy_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,8 @@ def find_packages(
if not constraint.is_any():
key = "{}:{}".format(key, str(constraint))

ignored_pre_release_versions = []

if self._cache.store("matches").has(key):
versions = self._cache.store("matches").get(key)
else:
Expand All @@ -256,28 +258,38 @@ def find_packages(
versions = []
for version in page.versions:
if version.is_prerelease() and not allow_prereleases:
if constraint.is_any():
# we need this when all versions of the package are pre-releases
ignored_pre_release_versions.append(version)
continue

if constraint.allows(version):
versions.append(version)

self._cache.store("matches").put(key, versions, 5)

for version in versions:
package = Package(name, version)
package.source_type = "legacy"
package.source_reference = self.name
package.source_url = self._url
for package_versions in (versions, ignored_pre_release_versions):
for version in package_versions:
package = Package(name, version)
package.source_type = "legacy"
package.source_reference = self.name
package.source_url = self._url

if extras is not None:
package.requires_extras = extras
if extras is not None:
package.requires_extras = extras

packages.append(package)
packages.append(package)

self._log(
"{} packages found for {} {}".format(len(packages), name, str(constraint)),
level="debug",
)
self._log(
"{} packages found for {} {}".format(
len(packages), name, str(constraint)
),
level="debug",
)

if packages or not constraint.is_any():
# we have matching packages, or constraint is not (*)
break

return packages

Expand Down
6 changes: 5 additions & 1 deletion poetry/repositories/pypi_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ def find_packages(
return []

packages = []
ignored_pre_release_packages = []

for version, release in info["releases"].items():
if not release:
Expand All @@ -138,6 +139,9 @@ def find_packages(
continue

if package.is_prerelease() and not allow_prereleases:
if constraint.is_any():
# we need this when all versions of the package are pre-releases
ignored_pre_release_packages.append(package)
continue

if not constraint or (constraint and constraint.allows(package.version)):
Expand All @@ -151,7 +155,7 @@ def find_packages(
level="debug",
)

return packages
return packages or ignored_pre_release_packages

def package(
self,
Expand Down
7 changes: 6 additions & 1 deletion poetry/repositories/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ def find_packages(
):
name = name.lower()
packages = []
ignored_pre_release_packages = []

if extras is None:
extras = []

Expand Down Expand Up @@ -71,6 +73,9 @@ def find_packages(
):
# If prereleases are not allowed and the package is a prerelease
# and is a standard package then we skip it
if constraint.is_any():
# we need this when all versions of the package are pre-releases
ignored_pre_release_packages.append(package)
continue

if constraint.allows(package.version):
Expand All @@ -89,7 +94,7 @@ def find_packages(

packages.append(package)

return packages
return packages or ignored_pre_release_packages

def has_package(self, package):
package_id = package.unique_name
Expand Down
10 changes: 10 additions & 0 deletions tests/repositories/fixtures/legacy/black.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<title>Links for black</title></head>
<body>
<h1>Links for black</h1>
<a href="https://files.pythonhosted.org/packages/b0/dc/ecd83b973fb7b82c34d828aad621a6e5865764d52375b8ac1d7a45e23c8d/black-19.10b0.tar.gz#sha256=c2edb73a08e9e0e6f65a0e6af18b059b8b1cdd5bef997d7a0b181df93dc81539" data-requires-python=">=3.6">black-19.10b0.tar.gz</a>
</body>
</html>
<!--SERIAL 6044498-->
Binary file not shown.
146 changes: 146 additions & 0 deletions tests/repositories/fixtures/pypi.org/json/black.json

Large diffs are not rendered by default.

21 changes: 21 additions & 0 deletions tests/repositories/test_legacy_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,27 @@ def test_find_packages_no_prereleases():
assert packages[0].source_url == repo.url


@pytest.mark.parametrize("constraint,count", [("*", 1), (">=1", 0), (">=19.0.0a0", 1)])
def test_find_packages_only_prereleases(constraint, count):
repo = MockRepository()
packages = repo.find_packages("black", constraint=constraint)

assert len(packages) == count

if count >= 0:
for package in packages:
assert package.source_type == "legacy"
assert package.source_reference == repo.name
assert package.source_url == repo.url


def test_find_packages_only_prereleases_empty_when_not_any():
repo = MockRepository()
packages = repo.find_packages("black", constraint=">=1")

assert len(packages) == 0


def test_get_package_information_chooses_correct_distribution():
repo = MockRepository()

Expand Down
8 changes: 8 additions & 0 deletions tests/repositories/test_pypi_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,14 @@ def test_find_packages_does_not_select_prereleases_if_not_allowed():
assert len(packages) == 1


@pytest.mark.parametrize("constraint,count", [("*", 1), (">=1", 0), (">=19.0.0a0", 1)])
def test_find_packages_only_prereleases(constraint, count):
repo = MockRepository()
packages = repo.find_packages("black", constraint=constraint)

assert len(packages) == count


def test_package():
repo = MockRepository()

Expand Down

0 comments on commit a357650

Please sign in to comment.