Commit b2b90755 by Arun Babu Neelicattu

Handle (*) constraint for pre-release only packages

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
parent a4334c0f
...@@ -246,6 +246,8 @@ class LegacyRepository(PyPiRepository): ...@@ -246,6 +246,8 @@ class LegacyRepository(PyPiRepository):
if not constraint.is_any(): if not constraint.is_any():
key = "{}:{}".format(key, str(constraint)) key = "{}:{}".format(key, str(constraint))
ignored_pre_release_versions = []
if self._cache.store("matches").has(key): if self._cache.store("matches").has(key):
versions = self._cache.store("matches").get(key) versions = self._cache.store("matches").get(key)
else: else:
...@@ -256,6 +258,9 @@ class LegacyRepository(PyPiRepository): ...@@ -256,6 +258,9 @@ class LegacyRepository(PyPiRepository):
versions = [] versions = []
for version in page.versions: for version in page.versions:
if version.is_prerelease() and not allow_prereleases: 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 continue
if constraint.allows(version): if constraint.allows(version):
...@@ -263,21 +268,28 @@ class LegacyRepository(PyPiRepository): ...@@ -263,21 +268,28 @@ class LegacyRepository(PyPiRepository):
self._cache.store("matches").put(key, versions, 5) self._cache.store("matches").put(key, versions, 5)
for version in versions: for package_versions in (versions, ignored_pre_release_versions):
package = Package(name, version) for version in package_versions:
package.source_type = "legacy" package = Package(name, version)
package.source_reference = self.name package.source_type = "legacy"
package.source_url = self._url package.source_reference = self.name
package.source_url = self._url
if extras is not None: if extras is not None:
package.requires_extras = extras package.requires_extras = extras
packages.append(package) packages.append(package)
self._log( self._log(
"{} packages found for {} {}".format(len(packages), name, str(constraint)), "{} packages found for {} {}".format(
level="debug", 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 return packages
......
...@@ -114,6 +114,7 @@ class PyPiRepository(RemoteRepository): ...@@ -114,6 +114,7 @@ class PyPiRepository(RemoteRepository):
return [] return []
packages = [] packages = []
ignored_pre_release_packages = []
for version, release in info["releases"].items(): for version, release in info["releases"].items():
if not release: if not release:
...@@ -138,6 +139,9 @@ class PyPiRepository(RemoteRepository): ...@@ -138,6 +139,9 @@ class PyPiRepository(RemoteRepository):
continue continue
if package.is_prerelease() and not allow_prereleases: 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 continue
if not constraint or (constraint and constraint.allows(package.version)): if not constraint or (constraint and constraint.allows(package.version)):
...@@ -151,7 +155,7 @@ class PyPiRepository(RemoteRepository): ...@@ -151,7 +155,7 @@ class PyPiRepository(RemoteRepository):
level="debug", level="debug",
) )
return packages return packages or ignored_pre_release_packages
def package( def package(
self, self,
......
...@@ -44,6 +44,8 @@ class Repository(BaseRepository): ...@@ -44,6 +44,8 @@ class Repository(BaseRepository):
): ):
name = name.lower() name = name.lower()
packages = [] packages = []
ignored_pre_release_packages = []
if extras is None: if extras is None:
extras = [] extras = []
...@@ -71,6 +73,9 @@ class Repository(BaseRepository): ...@@ -71,6 +73,9 @@ class Repository(BaseRepository):
): ):
# If prereleases are not allowed and the package is a prerelease # If prereleases are not allowed and the package is a prerelease
# and is a standard package then we skip it # 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 continue
if constraint.allows(package.version): if constraint.allows(package.version):
...@@ -89,7 +94,7 @@ class Repository(BaseRepository): ...@@ -89,7 +94,7 @@ class Repository(BaseRepository):
packages.append(package) packages.append(package)
return packages return packages or ignored_pre_release_packages
def has_package(self, package): def has_package(self, package):
package_id = package.unique_name package_id = package.unique_name
......
<!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-->
\ No newline at end of file
{
"info": {
"author": "\u0141ukasz Langa",
"author_email": "lukasz@langa.pl",
"bugtrack_url": null,
"classifiers": [
"Development Status :: 4 - Beta",
"Environment :: Console",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3 :: Only",
"Topic :: Software Development :: Libraries :: Python Modules",
"Topic :: Software Development :: Quality Assurance"
],
"description": "",
"description_content_type": "text/markdown",
"docs_url": null,
"download_url": "",
"downloads": {
"last_day": -1,
"last_month": -1,
"last_week": -1
},
"home_page": "https://github.com/psf/black",
"keywords": "automation formatter yapf autopep8 pyfmt gofmt rustfmt",
"license": "MIT",
"maintainer": "",
"maintainer_email": "",
"name": "black",
"package_url": "https://pypi.org/project/black/",
"platform": "",
"project_url": "https://pypi.org/project/black/",
"project_urls": {
"Homepage": "https://github.com/psf/black"
},
"release_url": "https://pypi.org/project/black/19.10b0/",
"requires_dist": [
"click (>=6.5)",
"attrs (>=18.1.0)",
"appdirs",
"toml (>=0.9.4)",
"typed-ast (>=1.4.0)",
"regex",
"pathspec (<1,>=0.6)",
"aiohttp (>=3.3.2) ; extra == 'd'",
"aiohttp-cors ; extra == 'd'"
],
"requires_python": ">=3.6",
"summary": "The uncompromising code formatter.",
"version": "19.10b0",
"yanked": false,
"yanked_reason": null
},
"last_serial": 6044498,
"releases": {
"19.10b0": [
{
"comment_text": "",
"digests": {
"md5": "067efd0498107b5fb2299fbfb000b0b6",
"sha256": "1b30e59be925fafc1ee4565e5e08abef6b03fe455102883820fe5ee2e4734e0b"
},
"downloads": -1,
"filename": "black-19.10b0-py36-none-any.whl",
"has_sig": true,
"md5_digest": "067efd0498107b5fb2299fbfb000b0b6",
"packagetype": "bdist_wheel",
"python_version": "py36",
"requires_python": ">=3.6",
"size": 97525,
"upload_time": "2019-10-28T23:53:54",
"upload_time_iso_8601": "2019-10-28T23:53:54.000711Z",
"url": "https://files.pythonhosted.org/packages/fd/bb/ad34bbc93d1bea3de086d7c59e528d4a503ac8fe318bd1fa48605584c3d2/black-19.10b0-py36-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"md5": "496632a95b73b8f5c5081d795a4e6af1",
"sha256": "c2edb73a08e9e0e6f65a0e6af18b059b8b1cdd5bef997d7a0b181df93dc81539"
},
"downloads": -1,
"filename": "black-19.10b0.tar.gz",
"has_sig": true,
"md5_digest": "496632a95b73b8f5c5081d795a4e6af1",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.6",
"size": 1019740,
"upload_time": "2019-10-28T23:54:05",
"upload_time_iso_8601": "2019-10-28T23:54:05.455213Z",
"url": "https://files.pythonhosted.org/packages/b0/dc/ecd83b973fb7b82c34d828aad621a6e5865764d52375b8ac1d7a45e23c8d/black-19.10b0.tar.gz",
"yanked": false,
"yanked_reason": null
}
]
},
"urls": [
{
"comment_text": "",
"digests": {
"md5": "067efd0498107b5fb2299fbfb000b0b6",
"sha256": "1b30e59be925fafc1ee4565e5e08abef6b03fe455102883820fe5ee2e4734e0b"
},
"downloads": -1,
"filename": "black-19.10b0-py36-none-any.whl",
"has_sig": true,
"md5_digest": "067efd0498107b5fb2299fbfb000b0b6",
"packagetype": "bdist_wheel",
"python_version": "py36",
"requires_python": ">=3.6",
"size": 97525,
"upload_time": "2019-10-28T23:53:54",
"upload_time_iso_8601": "2019-10-28T23:53:54.000711Z",
"url": "https://files.pythonhosted.org/packages/fd/bb/ad34bbc93d1bea3de086d7c59e528d4a503ac8fe318bd1fa48605584c3d2/black-19.10b0-py36-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"md5": "496632a95b73b8f5c5081d795a4e6af1",
"sha256": "c2edb73a08e9e0e6f65a0e6af18b059b8b1cdd5bef997d7a0b181df93dc81539"
},
"downloads": -1,
"filename": "black-19.10b0.tar.gz",
"has_sig": true,
"md5_digest": "496632a95b73b8f5c5081d795a4e6af1",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.6",
"size": 1019740,
"upload_time": "2019-10-28T23:54:05",
"upload_time_iso_8601": "2019-10-28T23:54:05.455213Z",
"url": "https://files.pythonhosted.org/packages/b0/dc/ecd83b973fb7b82c34d828aad621a6e5865764d52375b8ac1d7a45e23c8d/black-19.10b0.tar.gz",
"yanked": false,
"yanked_reason": null
}
]
}
...@@ -151,6 +151,27 @@ def test_find_packages_no_prereleases(): ...@@ -151,6 +151,27 @@ def test_find_packages_no_prereleases():
assert packages[0].source_url == repo.url 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(): def test_get_package_information_chooses_correct_distribution():
repo = MockRepository() repo = MockRepository()
......
...@@ -75,6 +75,14 @@ def test_find_packages_does_not_select_prereleases_if_not_allowed(): ...@@ -75,6 +75,14 @@ def test_find_packages_does_not_select_prereleases_if_not_allowed():
assert len(packages) == 1 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(): def test_package():
repo = MockRepository() repo = MockRepository()
......
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