Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New resolver error message is confusing if a package has inconsistent dependencies #8495

Open
uranusjr opened this issue Jun 25, 2020 · 22 comments
Assignees
Labels
C: dependency resolution About choosing which dependencies to install C: error messages Improving error messages UX User experience related

Comments

@uranusjr
Copy link
Member

Given this package:

# setup.py
from setuptools import setup
setup(
    name='testpkg',
    version='1',
    # virtualenv==20.0.25 requires six>=1.9.
    install_requires=['six<1.9', 'virtualenv==20.0.25'],
)

This produces the following error message:

ERROR: Cannot install testpkg 1 and testpkg because these package versions have conflicting dependencies.

The conflict is caused by:
    testpkg 1 depends on six<1.9
    virtualenv 20.0.25 depends on six<2 and >=1.9.0

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

ERROR: ResolutionImpossible For help visit: https://pip.pypa.io/en/stable/user_guide/#dependency-conflicts-resolution-impossible

testpkg shows up twice in the first ERROR: message, which looks confusing. It is “correct” that testpkg is conflicting with itself, but we probably need to produce a message that makes more sense to humans.

cc @nlhkabu @pfmoore

Note: I don’t think this should block beta since this kind of packages is already broken, and likely to be relatively rare. And the message is not that bad either; everything after the first line still makes sense in this situation.

@pfmoore
Copy link
Member

pfmoore commented Jun 25, 2020

Agreed this needs a different message (but also agreed it shouldn't block beta).

One question I would want to consider up front is whether the information available from a ResolutionImpossible exception gives us enough information to distinguish this case from the more general one. Maybe we should just provide as much as possible, and have resolvelib attach the whole "dependency tree so far" to the exception?

@uranusjr
Copy link
Member Author

I was actually thinking maybe we could get away with simply not showing a package name multiple times.

@pfmoore
Copy link
Member

pfmoore commented Jun 25, 2020

Hmm, maybe - nice bit of lateral thinking :-) Let's see what @nlhkabu thinks of that idea.

@nlhkabu nlhkabu self-assigned this Jul 8, 2020
@nlhkabu
Copy link
Member

nlhkabu commented Jul 8, 2020

Sorry - I must have missed this. Adding this ticket to the list of items I need to address.

@nlhkabu
Copy link
Member

nlhkabu commented Jul 14, 2020

+1 on @uranusjr's solution of only showing the package name once. We could change the initial line to something like:

"ERROR: Cannot install testpkg because of conflicting dependencies..."

@di
Copy link
Member

di commented Jul 30, 2020

I agree this needs a different message, but specifically I think we need to consider the use case that the user is just trying to install a dependency that they have no control over. As is, the suggested fixes would make no sense and would be out of the users' control

For example, if I'm just trying to install https://pypi.org/project/diamond-dependency/, I get:

pip install diamond-dependency --use-feature=2020-resolver
Collecting diamond-dependency
  Downloading diamond_dependency-1.0.0-py3-none-any.whl (1.1 kB)
Collecting sub-dependency-a
  Downloading sub_dependency_a-1.0.0-py3-none-any.whl (1.1 kB)
Collecting sub-dependency-b
  Downloading sub_dependency_b-1.0.0-py3-none-any.whl (1.1 kB)
ERROR: Cannot install diamond-dependency and diamond-dependency because these package versions have conflicting dependencies.

The conflict is caused by:
    sub-dependency-a 1.0.0 depends on sub-dependency-d<1.0.0
    sub-dependency-b 1.0.0 depends on sub-dependency-d>=1.0.0

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

ERROR: ResolutionImpossible For help visit: https://pip.pypa.io/en/stable/user_guide/#fixing-conflicting-dependencies

But if I am not a maintainer/owner of that package, and I don't know much about dependency specifications, the two proposed fixes would make little to no sense to me. Even if I did know something about what that means, it would be entirely out of my control. The actual "fix" would be to reach out to the maintainer of the package, which seems related to #8492.

@pradyunsg
Copy link
Member

Coming to this with fresh eyes, I'm wondering if what we should do here is drop the suggestions for how to fix this from the printed message.

Of course, that'll mean we only provide users information for diagnosing the issues with dependency conflicts from the documentation URL. OTOH, "advanced"/"expert" users would have a reasonable idea of what to do when they see this error, and non-expert users would not be presented with non-actionable suggestions without additional context.

@di
Copy link
Member

di commented Aug 26, 2020

Does pip have the ability to determine if a conflict is coming from a top-level (user-supplied) dependency or a sub-dependency?

@uranusjr
Copy link
Member Author

It does. Is the proposal to show different suggestions in different situations? What should the different messages be?

@di
Copy link
Member

di commented Aug 27, 2020

Well, if it's two top-level dependencies, it's within the user's control and the message above makes sense. If either one or both are sub-dependencies, it's out of the users control, but we could maybe guide them towards communicating with the project's maintainers instead.

@brainwane
Copy link
Contributor

Per conversation today, the next step here is to develop concrete wording for the error message change. It would be nice to have this in time for pip 20.3 but it's also okay to finish and merge it in a patch/point release after the 20.3 release.

@nlhkabu
Copy link
Member

nlhkabu commented Oct 13, 2020

Cross referencing #8492 as it seems these two issues can be resolved by a single PR that involves rewriting the error message :)

@nlhkabu
Copy link
Member

nlhkabu commented Oct 13, 2020

Extending/improving my proposal from #8492:

Both packages top level:

ERROR: Cannot install package_1 and package_2 because these package versions have conflicting dependencies.

The conflict is caused by:
    package_1 requires six<1.9
    package_2 requires six<2 and >=1.9.0

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

ERROR: ResolutionImpossible For help visit: https://pip.pypa.io/en/stable/user_guide/#dependency-conflicts-resolution-impossible

At least one package top level, at least one package deeper in dep tree:

ERROR: Cannot install package_1 and package_2 because these package versions have conflicting dependencies.

The conflict is caused by:
    package_1 requires six<1.9
    package_2 requires six<2 and >=1.9.0

Dependency tree:
- package_1 requires six<1.9
- package_4 requires package_3
  - package_3 requires package_2
    - package_2 requires six<2 and >=1.9.0

To fix this you could try to:
- loosen the range of package versions you've specified
- remove package versions to allow pip to attempt to solve the dependency conflict
- ask the package maintainers to loosen their dependencies

ERROR: ResolutionImpossible For help visit: https://pip.pypa.io/en/stable/user_guide/#dependency-conflicts-resolution-impossible

Both packages deep in dep tree:

ERROR: Cannot install package_1 and package_2 because these package versions have conflicting dependencies.

The conflict is caused by:
    package_1 requires six<1.9
    package_2 requires six<2 and >=1.9.0

Dependency tree:
- package_5 requires package_1
  - package_1 requires six<1.9
- package_4 requires package_3
  - package_3 requires package_2
    - package_2 requires six<2 and >=1.9.0

To fix this you could try to:
- ask the package maintainers to loosen their dependencies

ERROR: ResolutionImpossible For help visit: https://pip.pypa.io/en/stable/user_guide/#dependency-conflicts-resolution-impossible

Package conflicting with itself

ERROR: Cannot install testpkg because of conflicting dependencies.

The conflict is caused by:
    testpkg requires six<1.9
    testpkg requires six<2 and >=1.9.0

Dependency tree:
- testpkg requires six<1.9
- testpkg requires virtualenv==20.0.25
  - virtualenv requires six<2 and >=1.9.0

To fix this you could try to:
- ask the package maintainers to fix the conflict

ERROR: ResolutionImpossible For help visit: https://pip.pypa.io/en/stable/user_guide/#dependency-conflicts-resolution-impossible

Not sure this all makes sense? May also be a bit too verbose? Would appreciate your feedback on this @di, @pradyunsg, @pfmoore, @uranusjr.

@nlhkabu
Copy link
Member

nlhkabu commented Oct 13, 2020

Note: if we update the error messages here, we will also need to update the documentation

@ei8fdb
Copy link
Contributor

ei8fdb commented Oct 13, 2020

These 4 messages are clear to me @nlhkabu. They do require knowledge of concepts, language but that's another point.

Do we have time to send this to a number of UX panel participants? Asking them "if you saw these messages, what is your understanding of them?"

In short: To me they are satifactory. If we can test them with 8-9 users, then even better.

@uranusjr
Copy link
Member Author

I think in the “Both packages top level” it is still possible the conflicts cannot be resolved by loosening package_1 and package_2, and should offer the “ask the package maintainers” solution. (And that would make the case identical to “At least one package top level”.)

@nlhkabu
Copy link
Member

nlhkabu commented Oct 22, 2020

Updates after feedback from @pradyunsg and @uranusjr

Note: It is not currently possible to display the dependency tree, but pip does know the parent of the conflicting package (or if no parent exists)

Accordingly, we should update the messages to be:

Conflict caused by dependencies

ERROR: Cannot install package_1 and package_2 because these package
versions have conflicting dependencies.

The conflict is caused by:
    package_1 2.3 requires package_3>2.0
    package_2 1.0 requires package_3<2.0

To fix this you could try to:
- loosen the range of package versions you've specified
- remove package versions to allow pip to attempt to solve the
dependency conflict
- ask the package maintainers to loosen their dependencies

ERROR: ResolutionImpossible For help visit: https://pip.pypa.io/en/st
able/user_guide/#dependency-conflicts-resolution-impossible

Conflict includes top level requirement

ERROR: Cannot install package_2 and package_3 because these package
versions have conflicting dependencies.

The conflict is caused by:
    package_2 1.0 requires package_3<2.0
    package_3>2.0 is required by you

To fix this you could try to:
- loosen the range of package versions you've specified
- remove package versions to allow pip to attempt to solve the
dependency conflict
- ask the package maintainers to loosen their dependencies

ERROR: ResolutionImpossible For help visit: https://pip.pypa.io/en/st
able/user_guide/#dependency-conflicts-resolution-impossible

Package conflicting with itself

ERROR: Cannot install package_1 because of conflicting dependencies.

The conflict is caused by:
    package_1 requires package_3<2.0
    package_1 requires package_3>2.0

To fix this you could try to:
- ask the package maintainers to fix the conflict

ERROR: ResolutionImpossible For help visit: https://pip.pypa.io/en/st
able/user_guide/#dependency-conflicts-resolution-impossible

@nlhkabu
Copy link
Member

nlhkabu commented Oct 22, 2020

New issue opened to look at adding dep tree to error message: #9036

@brainwane
Copy link
Contributor

Per our meeting in late October we'd like to have this in the 20.3 release.

@brainwane
Copy link
Contributor

@pradyunsg is working on this.

@brainwane
Copy link
Contributor

We had another discussion in early November and decided that it might be okay to release 20.3 without fixing this. @pradyunsg you've now had more time to consider this since then, so use your judgment to retain or change this issue's blocker status.

@brainwane brainwane removed this from the 20.3 milestone Nov 20, 2020
@brainwane
Copy link
Contributor

I have re-reviewed this issue and #8884 which is related.

Given how much we've had to delay the release of 20.3 to fix issues and reduce disruption to users, and given the work still left to do before we can release it, I've decided that fixing this particular non-optimal error message is something that can wait until after the 20.3 release.

@pradyunsg pradyunsg added C: dependency resolution About choosing which dependencies to install and removed C: new resolver labels Oct 12, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C: dependency resolution About choosing which dependencies to install C: error messages Improving error messages UX User experience related
Projects
None yet
Development

No branches or pull requests

7 participants