diff --git a/news/6744.bugfix.rst b/news/6744.bugfix.rst new file mode 100644 index 000000000..1cbb9055a --- /dev/null +++ b/news/6744.bugfix.rst @@ -0,0 +1,3 @@ +Fix ``pipenv lock`` failing with ``Invalid requirement: 'colorama*'`` when a default package has markers that exclude the current platform, +such as ``colorama = {version = "*", markers = "sys_platform == 'win32'"}``, and the Pipfile also has ``[dev-packages]``. +The default section's locked ``"*"`` entry was turned into an invalid constraint for the develop resolution. diff --git a/pipenv/utils/dependencies.py b/pipenv/utils/dependencies.py index 6d6b4658f..06b678fd2 100644 --- a/pipenv/utils/dependencies.py +++ b/pipenv/utils/dependencies.py @@ -1574,7 +1574,9 @@ def get_constraints_from_resolved_deps(resolved_deps): if any(k in dep_info for k in ("path", "file", "git", "hg", "svn", "bzr")): continue version = dep_info.get("version") - if version: + # A package skipped by its markers is locked as "*": there is no pin + # to carry over, and "name*" is not a valid requirement. + if version and not is_star(version): canonical = canonicalize_name(dep_name) constraints.add(f"{canonical}{version}") return constraints diff --git a/tests/unit/test_dependencies.py b/tests/unit/test_dependencies.py index fdf41ef06..c33944be1 100644 --- a/tests/unit/test_dependencies.py +++ b/tests/unit/test_dependencies.py @@ -998,6 +998,21 @@ def test_empty_deps(self): assert get_constraints_from_resolved_deps({}) == set() + def test_skips_wildcard_versions(self): + """A package whose markers exclude the locking platform is locked as "*". + + Writing it as ``colorama*`` made pip reject the constraints file, so + locking a dev category failed (``Invalid requirement: 'colorama*'``). + """ + from pipenv.utils.dependencies import get_constraints_from_resolved_deps + + resolved = { + "colorama": {"markers": "sys_platform == 'win32'", "version": "*"}, + "normal": {"version": "==1.0"}, + } + constraints = get_constraints_from_resolved_deps(resolved) + assert constraints == {"normal==1.0"} + def test_canonicalizes_names(self): from pipenv.utils.dependencies import get_constraints_from_resolved_deps