diff --git a/news/1901.bugfix b/news/1901.bugfix new file mode 100644 index 0000000000..7106fe6599 --- /dev/null +++ b/news/1901.bugfix @@ -0,0 +1 @@ +Fixed an ongoing bug which sometimes resolved incompatible versions into lockfiles. diff --git a/pipenv/patched/piptools/utils.py b/pipenv/patched/piptools/utils.py index 12c3991a81..388ddd004b 100644 --- a/pipenv/patched/piptools/utils.py +++ b/pipenv/patched/piptools/utils.py @@ -11,7 +11,8 @@ from ._compat import InstallRequirement from first import first -from pip._vendor.packaging.specifiers import SpecifierSet, InvalidSpecifier +from pipenv.patched.notpip._vendor.packaging.specifiers import SpecifierSet, InvalidSpecifier +from pipenv.patched.notpip._vendor.packaging.version import Version, InvalidVersion, parse as parse_version from .click import style @@ -21,6 +22,7 @@ def clean_requires_python(candidates): """Get a cleaned list of all the candidates with valid specifiers in the `requires_python` attributes.""" all_candidates = [] + py_version = parse_version(os.environ.get('PIP_PYTHON_VERSION', str(sys.version_info[:3]))) for c in candidates: if c.requires_python: # Old specifications had people setting this to single digits @@ -28,9 +30,12 @@ def clean_requires_python(candidates): if c.requires_python.isdigit(): c.requires_python = '>={0},<{1}'.format(c.requires_python, int(c.requires_python) + 1) try: - SpecifierSet(c.requires_python) + specifierset = SpecifierSet(c.requires_python) except InvalidSpecifier: continue + else: + if not specifierset.contains(py_version): + continue all_candidates.append(c) return all_candidates diff --git a/tasks/vendoring/patches/patched/piptools.patch b/tasks/vendoring/patches/patched/piptools.patch index 522c13d82e..010e726b1b 100644 --- a/tasks/vendoring/patches/patched/piptools.patch +++ b/tasks/vendoring/patches/patched/piptools.patch @@ -539,15 +539,16 @@ index 08dabe1..480ad1e 100644 else: return self.repository.find_best_match(ireq, prereleases) diff --git a/pipenv/patched/piptools/utils.py b/pipenv/patched/piptools/utils.py -index fde5816..5827a55 100644 +index fde5816..fb71882 100644 --- a/pipenv/patched/piptools/utils.py +++ b/pipenv/patched/piptools/utils.py -@@ -11,13 +11,30 @@ from contextlib import contextmanager +@@ -11,13 +11,35 @@ from contextlib import contextmanager from ._compat import InstallRequirement from first import first - +from pip._vendor.packaging.specifiers import SpecifierSet, InvalidSpecifier ++from pip._vendor.packaging.version import Version, InvalidVersion, parse as parse_version from .click import style @@ -557,6 +558,7 @@ index fde5816..5827a55 100644 +def clean_requires_python(candidates): + """Get a cleaned list of all the candidates with valid specifiers in the `requires_python` attributes.""" + all_candidates = [] ++ py_version = parse_version(os.environ.get('PIP_PYTHON_VERSION', str(sys.version_info[:3]))) + for c in candidates: + if c.requires_python: + # Old specifications had people setting this to single digits @@ -564,9 +566,12 @@ index fde5816..5827a55 100644 + if c.requires_python.isdigit(): + c.requires_python = '>={0},<{1}'.format(c.requires_python, int(c.requires_python) + 1) + try: -+ SpecifierSet(c.requires_python) ++ specifierset = SpecifierSet(c.requires_python) + except InvalidSpecifier: + continue ++ else: ++ if not specifierset.contains(py_version): ++ continue + all_candidates.append(c) + return all_candidates + @@ -574,7 +579,7 @@ index fde5816..5827a55 100644 def key_from_ireq(ireq): """Get a standardized key for an InstallRequirement.""" if ireq.req is None and ireq.link is not None: -@@ -43,16 +60,51 @@ def comment(text): +@@ -43,16 +65,51 @@ def comment(text): return style(text, fg='green') @@ -630,7 +635,7 @@ index fde5816..5827a55 100644 def format_requirement(ireq, marker=None): -@@ -63,10 +115,10 @@ def format_requirement(ireq, marker=None): +@@ -63,10 +120,10 @@ def format_requirement(ireq, marker=None): if ireq.editable: line = '-e {}'.format(ireq.link) else: