question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

pip resolver installing incompatible versions

See original GitHub issue

Description

See reproduce steps for setup.

It installed certifi==2021.5.30, and then reported an error for a version mismatch. Instead, pip should have looked at the requirements and installed 2020.12.5 to work with all the other dependencies.

It seems that passing --upgrade makes it work.

Ref: https://github.com/linkedin/datahub/issues/2717

Expected behavior

It should have installed certifi==2020.12.5, since the main requirements are certifi<2021.0.0 and greater than a version from 2017.

pip version

21.1.2

Python version

3.8.6

OS

MacOS

How to Reproduce

The following steps:

python3.8 -m venv venv
source venv/bin/activate
pip install --upgrade pip wheel setuptools  # sanity check
pip freeze  # empty, since I'm in a fresh venv
PIP_RESOLVER_DEBUG=1 pip install 'acryl-datahub[snowflake]==0.8.1.2'

Yields:

ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
snowflake-connector-python 2.4.5 requires certifi<2021.0.0, but you have certifi 2021.5.30 which is incompatible.

Output

Edited by @uranusjr: I put this into a Gist instead since the log is way too long to reasonably read and reference in comments.

https://gist.github.com/uranusjr/74ec344ce72f9c9cbe91b262bcd49dd5

Code of Conduct

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:3
  • Comments:9 (7 by maintainers)

github_iconTop GitHub Comments

4reactions
uranusjrcommented, Jun 19, 2021

I dug into for like two hours and finally think I know what’s going on.

The trigger to this issue is that snowflake-connector-python specifies certifi twice. From the wheel’s metadata:

Metadata-Version: 2.1
Name: snowflake-connector-python
Version: 2.4.5
...
Requires-Dist: certifi (<2021.0.0)
...
Requires-Dist: certifi (>=2017.4.17)
...

A wrikle to this is that there’s a reproducibility issue, because the issue only happen when certifi<2021.0.0 is fed into the resolver before certifi>=2017.4.17. But pkg_resources shuffles the Requires-Dist values on calculation, so to reproduce this deterministically, you need to change line 3041 of pkg_resources.DistInfoDistribution._compute_dependencies() to something like:

dm[None].extend(reqs_for_extra(None))

so the order of requirements don’t change between runs.

Now onto the actual resolver stuff. When the resolver pins through a candidate, it converts all of the candidate’s dependencies into criteria so they can be merged into existing criteria:

https://github.com/pypa/pip/blob/7c3abccd22c4bbd6c1da2ae41845ffbd26c1bb17/src/pip/_vendor/resolvelib/resolvers.py#L200-L205

But it uses a dict for the job. So when a candidate specifies a package multiple times (like snowflake-connector-python), the latter specification would override the previous one. Since certifi<2021.0.0 is specified first (after we patch pkg_resources; without the patch the resolver has 50% chance to get the “right” one), it got lost during resolution.

I have to say, I haven’t had such an exercise debugging an issue like this for quite a while. This kind of things is why I’m doing open source work, so thanks for that, in a way 😆 I’m unfortunately quite busy tomorrow (it’s late Saturday here), but will try to find some time to fix asap.

2reactions
uranusjrcommented, Jun 19, 2021

I can reproduce this in a fresh virtual environment. This is very weird. I suspect there is a package doing funky things to bypass the resolver and install its own things.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Why is pip installing an incompatible package version?
Pip does not have a dependency resolver. If you tell it to install package foo without any qualifications, you're getting the newest version...
Read more >
Dependency Resolution - pip documentation v22.3.1
Sometimes the packages that you have asked pip to install are incompatible because you have been too strict when you specified the package...
Read more >
The Nine Circles of Python Dependency Hell - Medium
If you just run pip install -r requirements.txt , pip will happily ignore any conflicting versions of libraries. In the best case, your...
Read more >
Understanding Python Packages pip Dependency Resolver ...
The exact version of C to be downloaded and installed has to be figured out by pip intelligently. It does not install multiple...
Read more >
Python Dependencies - Everything You Need to Know
Unfortunately, pip makes no attempt to resolve dependency conflicts. For example, if you install two packages, package A may require a different ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found