Skip to content

Causes returned by _attempt_to_pin_criterion are too broad (causing searching unnecessary parts of a dependency graph) #171

@notatallshaw

Description

@notatallshaw

In a complex resolution the causes returned by _attempt_to_pin_criterion when rejecting a candidate are far too broad, if we take a look at the example in pypa/pip#13037 (comment) I've created a log that prints out each rejection: pypa/pip#13037 (comment)

Looking at one of the rejections:

Rejecting thinc 8.3.1, due to conflict:
	The user requested numpy==1.21.5
	spacy 3.8.2 depends on numpy>=1.19.0; python_version >= "3.9"
	mlflow 2.17.0 depends on numpy<3
	matplotlib 3.8.4 depends on numpy>=1.21
	pandas 2.0.3 depends on numpy>=1.21.0; python_version >= "3.10"
	pyarrow 17.0.0 depends on numpy>=1.16.6
	scikit-learn 1.5.2 depends on numpy>=1.19.5
	scipy 1.10.1 depends on numpy<1.27.0 and >=1.19.5
	thinc 8.3.1 depends on numpy<2.1.0 and >=2.0.0; python_version >= "3.9"

This should be ideally narrowed to:

Rejecting thinc 8.3.1, due to conflict:
	The user requested numpy==1.21.5
	thinc 8.3.1 depends on numpy<2.1.0 and >=2.0.0; python_version >= "3.9"

This would allow downstream libraries (like pip) that use cases to prefer backtracking to hone in on the correct causes, and it would produce a much more focused message to the user, especially when hitting an impossible resolution.

Because resolvelib is so generic a cause narrowing is a little tricky, but I propose the following steps:

  1. While there are more than 2 causes, loop through each of the causes
  2. Remove that cause and confirm there is still a conflict in the remaining causes
  3. Check there is no conflict between the removed cause and any remaining cause
  4. If the above criteria pass remove it from the cause list

I think this could be a huge speed up for very problamatic resolutions where the downstream library uses the causes to determine what to prefer, I will look to make a PR in the coming weeks.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions