pip: New resolver reports version conflict on github repo URL variations

The resolver appears to treat projectname @ git+https://git@github.com/org/repo.git as different from projectname @ git+https://github.com/org/repo.git even though they’re the same thing and the only difference is the “git@” in the url. If something is required directly and indirectly (via another requirement) using slightly different but totally valid URL variations, pip fails with a version conflict error.

pip install -r requirements.txt on a requirements.txt containing:

project-abc @ git+https://github.com/org/project-abc.git
project-def @ git+https://github.com/org/project-def.git

Where project-def has a requirements.txt containing the “git@” URL variant:

project-abc @ git+https://git@github.com/org/project-abc.git

Produces

ERROR: Cannot install -r requirements.txt (line 2) ... because these package
versions have conflicting dependencies.

The conflict is caused by:
    The user requested project-abc 0.1.0 (from git+https://github.com/org/project-abc.git)
    project-def 0.1.2 depends on project-abc 0.1.0 (from git+https://****@github.com/org/project-abc.git)

To fix this you could try to:
1. loosen the range of package versions you've specified
2. remove package versions to allow pip attempt to solve the dependency conflict

Removing the “user@” from the second requirements.txt avoids this, but it worked before the resolver upgrade and may require changes to packages upstream from the user.

Expected Behavior

Working URL variations for the same package should not affect version resolution.

Environment details

pip 20.3.1 macOS Mojave 10.14.6 Python 3.8.6

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 21 (8 by maintainers)

Commits related to this issue

Most upvoted comments

It is possible, but would require a feature request and substantial discussion, since the current behaviour (use the revision pointed by the default branch) is well-established and likely depended by many.

Variants of a Python package are ultimately identified by their versions, and this mechanism is built into many areas of Python. PEP 508 URL is a mean to specify where pip should download things to satisfy a package version request. By giving semantics to a Git URL’s revision information, we’d essentially introduce an alternative versioning scheme parallel to the package’s version metadata, which would not play well with other parts of packaging. Not that the revision can’t be used as package version—Go’s packaging solution does basically that—but the scheme does not work well in Python packaging without substential designing to fit into the current version system.

Wouldn’t it possible to modify pip so that it at least considers that when the urls just differ by presence / absence of a commit hash, the one without the commit hash should be considered as satisfied by the one with the commit hash?

From pip’s perspective, any URL spec is pinning the requirement. So it does not really matter; by using a URL is setup.py, you’re already pinning.