diff --git a/poetry/repositories/legacy_repository.py b/poetry/repositories/legacy_repository.py
index 901e144f956..fed921e5f77 100644
--- a/poetry/repositories/legacy_repository.py
+++ b/poetry/repositories/legacy_repository.py
@@ -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:
@@ -256,6 +258,9 @@ 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):
@@ -263,21 +268,28 @@ def find_packages(
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
diff --git a/poetry/repositories/pypi_repository.py b/poetry/repositories/pypi_repository.py
index c9f320400c5..6ea50bd84dc 100644
--- a/poetry/repositories/pypi_repository.py
+++ b/poetry/repositories/pypi_repository.py
@@ -114,6 +114,7 @@ def find_packages(
return []
packages = []
+ ignored_pre_release_packages = []
for version, release in info["releases"].items():
if not release:
@@ -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)):
@@ -151,7 +155,7 @@ def find_packages(
level="debug",
)
- return packages
+ return packages or ignored_pre_release_packages
def package(
self,
diff --git a/poetry/repositories/repository.py b/poetry/repositories/repository.py
index cea554ef47d..85aac6ddabc 100644
--- a/poetry/repositories/repository.py
+++ b/poetry/repositories/repository.py
@@ -44,6 +44,8 @@ def find_packages(
):
name = name.lower()
packages = []
+ ignored_pre_release_packages = []
+
if extras is None:
extras = []
@@ -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):
@@ -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
diff --git a/tests/repositories/fixtures/legacy/black.html b/tests/repositories/fixtures/legacy/black.html
new file mode 100644
index 00000000000..333fd93ef02
--- /dev/null
+++ b/tests/repositories/fixtures/legacy/black.html
@@ -0,0 +1,10 @@
+
+
+
+ Links for black
+
+ Links for black
+ black-19.10b0.tar.gz
+
+
+
\ No newline at end of file
diff --git a/tests/repositories/fixtures/pypi.org/dists/black-19.10b0-py36-none-any.whl b/tests/repositories/fixtures/pypi.org/dists/black-19.10b0-py36-none-any.whl
new file mode 100644
index 00000000000..3d031c0f3ef
Binary files /dev/null and b/tests/repositories/fixtures/pypi.org/dists/black-19.10b0-py36-none-any.whl differ
diff --git a/tests/repositories/fixtures/pypi.org/json/black.json b/tests/repositories/fixtures/pypi.org/json/black.json
new file mode 100644
index 00000000000..f4e244d1b22
--- /dev/null
+++ b/tests/repositories/fixtures/pypi.org/json/black.json
@@ -0,0 +1,146 @@
+{
+ "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
+ }
+ ]
+}
diff --git a/tests/repositories/test_legacy_repository.py b/tests/repositories/test_legacy_repository.py
index 1b29cc4c36f..189de7fd294 100644
--- a/tests/repositories/test_legacy_repository.py
+++ b/tests/repositories/test_legacy_repository.py
@@ -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()
diff --git a/tests/repositories/test_pypi_repository.py b/tests/repositories/test_pypi_repository.py
index e095e9c10cf..61c588860ba 100644
--- a/tests/repositories/test_pypi_repository.py
+++ b/tests/repositories/test_pypi_repository.py
@@ -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()