-
Notifications
You must be signed in to change notification settings - Fork 3k
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
Relaxing / Ignoring constraints during dependency resolution #8076
Comments
@stonebig Would you mind separate the other wishes part into their own issues? It would be much easier to discuss them that way. As for relxing, I am honestly uncomfortable with having such a impactful feature handy for the general audience. I was by chance also having a similar discussion in the Pipenv tracker, and both the Pipenv one and your are exactly situations I personally think the maintainers have a valid point to restrict the versions, and a user should not be able to override them easily. It’s still useful to have this option somewhere since indeed there are packages with incorrect metadata out there, but pip is too low in the packaging management realm to implement the feature IMO. |
Ok, separating other whishes in a few minutes.
|
Thanks for filing this @stonebig! I've gone ahead and re-titled this to issue to be more clearly scoped. We have seen multiple groups of users express interest in a feature like this. @pfmoore @uranusjr and I have had this come up in our discussions during our work on the resolver, and we are aware of this user need. We don't know how exactly this would work and what approach we'd be taking here -- we're gonna visit this specific topic at a later date, once the new resolver implementation is at feature parity with the current resolver. |
This is a completely separate request, and can be built outside of pip and doesn't need to be built into pip. If someone wants to build this outside of pip and later propose bringing it into pip (with clear reasoning for why it can't live outside pip), that'd be perfect. I don't think pip's maintainers are going to be developing/integrating this into pip, and I welcome others to try to build such tooling on-top-of or outside of pip. I think there has been a "pip GUI" project undertaken as part of IDLE in the past, but I don't have the time to take a look right now. :) |
This comment has been minimized.
This comment has been minimized.
Building a dsitribution WinPython is quite simple:
I dream of a way to reverse the problem:
|
Just to note that, while I agree that over-restrictive requirements can be an issue1, this is a fairly specialised use case. It's not that dependencies can't clash, but that putting together a Python distribution involves including (and managing) a lot of libraries that potentially have no "natural" reason to expect to be used together. So dependency clashes that the library maintainers haven't anticipated/haven't seen before are likely to be more common. Using It's also entirely possible that pip could have options to ignore or relax certain dependency constraints. As a general problem, it could be hard to get a good UI for this (we're currently explicitly doing user research into what users want from the new dependency resolution - @ei8fdb you may want to invite @stonebig to get involved in that, if they aren't already). And I worry that while such a feature would be invaluable for specialists like @stonebig, it could easily be abused by naive users ("Cannot install X because Y is installed" - "just say --ignore-dependency=Z") and generate more confusion than it addresses - that's a further trade-off that we need to consider. Sorry, there's no immediate answers in this, but hopefully it adds some context to the issue and explains what we're looking at when deciding how to address it. I should also point out that this may not be something that makes it into the initial release of the resolver. Correct behaviour while satisfying the declared dependencies has to be the first priority, as I'm sure you'll understand. So 1 I've made the argument myself that libraries should avoid over-restricting dependencies. |
There are some more use cases outlined in python-poetry/poetry#697 |
The use cases noted in the poetry issues are good to have as examples of where strict dependency resolution can cause issues, but I'm in agreement with @sdispater that ignoring declared dependency data is very dangerous and not usually the right way to handle this issue. If a project declares certain dependency data then there are three possibilities:
In pip's case, If there is a genuine need for dependency data overrides, that pip has to address, then I would argue that the need is not limited to a single tool, and should be standardised - maybe a "local metadata override file", whose format is standardised and can be implemented by any tool that does dependency resolution (pip, poetry, pipenv, ...). This would mean that users can declare such overrides once, and not be tied to a single tool's implementation. It also means that any edge cases and potential risks can be identified and addressed once, rather than having every project go through the same process. |
Adding my use case from #8307 for ignoring a pinned sub-dependency when that dependency is the thing being developed locally. In Jinja, I started pinning development dependencies with pip-compile from pip-tools. One of the development dependencies is Sphinx to build the docs. Sphinx has a dependency on (the latest release of) Jinja, so pip-compile adds a pin for Jinja. I want to provide one pip command for new contributors to set up their development environment with the the pinned dev dependencies and Jinja in editable mode. I want this command to remain simple, so that new contributors can have an easy time getting started.
However, the pinned sub-dependency on Jinja takes precedence over the direct flag to install in editable mode, so I have a similar issue with Click. It has a dev dependency on pip-tools, which has a dependency on Click. A few new contributors were confused because I see |
If you don't mind, I'm going to leave the question of how you view You say you have the latest production version of Jinja pinned in your I wonder if the problem here is that your workflow, or the tools you are using, are resulting in over-strict pinning, which means that having |
Neither pip-tools nor Dependabot (which uses pip-tools) have the capability of doing anything but pinning exact dependencies. Both those projects are fairly common now, it's why I chose them. Plenty of other projects will be using them, I'm just in the more unique case that I develop projects that the projects I depend on depend on. I'm not really clear what pip-tools could do here, since it's designed to pin exact versions. Jinja isn't a direct dependency of itself, all there is in the template file is Sphinx. Anything pip-tools does also needs to be understood by Dependabot, otherwise we lose automation. If you have any input about that, I opened an issue a while ago before I opened an issue here: jazzband/pip-tools#1150. |
That’s my assumption as well. |
Agreed. We need to be 100% clear that this will instruct pip to create a broken environment (in terms of the declared dependency metadata) and it's the user's responsibility to manage this. We should stick to the principle that pip expects the target environment to pass |
Ah yes I did not think of all the weird things you can do in a requirements file. I agree with all of that and in general think it should be a restrictive subset of requirements, on top of this I would say no "flag options" (e.g. a requirements file can have I would also say no requirement that contains extras (e.g. The target use case, in general. is that the user is only limiting 1 package e.g.
Yes exactly, sorry for the poor wording. The idea is the "override constraints" are only valid, at most, during a single install command and does not affect packages in any permanent way.
Yes, the idea is is that only the user can provide an "override constraints" file, they would need to pass it in every time they wanted it. A package can not automatically provide one, this is only a user level/pip option not something that is available to packages generally. |
I wanted to point out some limitations of my proposal, firstly it does not support something like: "If I have package "abc"<=1 then I want to force "xyz"<2, but if package "abc">1 then "xyz" does not need to be forced". The proposal assumes the use case that the user will put in their requirements or constraints file "abc"<=1 or "abc">1 and then set their override file appropriately. I feel like this is sufficient for situations where users really want to install conflicting dependencies as they should have a very strong understanding of their requirements and constraints. Also worth noting is that backtracking may produce "surprising" results but again the assumption is a use case where users have a strong understanding of their requirements and constraints and should be able to mostly avoid backtracking with a mix of requirements, constraints, overrides (and maybe one day pip will add a flag to not attempt to backtrack and just error out which could be useful). |
+1 We already have the great constraints file, where we can manually specify version of dependencies ( For example, assume that package With Implementation would be super simple - just override the dependency version requirement if it conflicts with the constraint, and log a warning. |
This proposal is great. If this proposal can be finished in a way that PyPI maintainers are willing to accept, I would love to discuss how we (@NabuCasa / @home-assistant) can sponsor someone to build this feature. Prefer to sponsor a maintainer or active contributor to pip. |
I started on a PR to fix this issue. I think my code works for the problems described here. My use case is a bit different though, so I won't finish the PR and have just closed it. But I would be happy if someone picks up my work in their own PR. The summary is in this comment: #11537 (comment)
The first item is something anyone can help with: try out my PR and see if that fixes your problem or not, and report it back. |
@mauritsvanrees I like #11537 and while I have not tested it, I think it solves our issues. I agree with @pfmoore that adding this type of syntax adds more complexity and that a separate overrides file is preferable, at least for now. In the future I can imagine a single new style file but that should really be out of scope here. Alternatively, I could imagine a new operator (version specifier?) for this, |
In #9948, we're discussing adding a per-requirement If the proposed solution there works for you, please leave a 👍🏽 reaction on this comment or let us know on that issue why your usecase isn't something workable with that. |
Here's a "bigger picture" question that I briefly mentioned above but I think should be made explicit. Are we willing to support people using pip in already-broken environments? Suppose for example, we get a bug report " I'm fine with us saying we won't support that. And I'd be happy with having a requirement that we can only investigate bugs reported with either a reproducer that starts from an empty environment, or where the user has explicitly confirmed that I'm sure that the people with use cases who need this functionality would use it appropriately and with care (no sarcasm here, genuinely). It's the people who find advice on the internet and use it inappropriately without understanding the implication ("just use |
by broken do you mean but actually, isn't it already the case ipso-facto (that pip running/installing in already "broken" env is allowed/supported) ? I mean it's not like, for instance, debian apt that refuses to continue installing new packages if one(or more) of them are actually "broken" and not fixed (in some sense of "broken", as far as I know).
I would guess/hope that someone would ask to |
No. There are many reasons why pip doesn't run
It's surprisingly uncommon that we ask that. To an extent that's what I'm saying, do we want to start with "please run |
If a pip environment is already broken, people may need tools to unbreak it. At the minimum, if I think it should work like this, and I have no idea if that is the case now:
That said: I think it is fair to update the bug report issue template to ask people to include the output of |
It's a while since I checked the details, but from what I recall, There are plenty of ways you can use documented pip features to break an environment. The obvious trivial one is To be clear, I'm talking here about "broken" in the sense of "some dependency metadata isn't satisfied". You can break environments in other ways (manually delete files, for example) that will leave pip unusable. You're on your own in that case. |
Interesting, at least for the:
Adding the pipdeptree style features would be great, especially if accessible by api/not using the command line |
What's the problem this feature will solve?
Puting together some packages that have by default incompatible constraints.
Indeed:
. "accepting complains on this known/focus set of package",
. you're on your own support if you deviate, but not necessarly bad.
==> The new resolver may create more problems than solutions, when trying to build an environment with a large set of package.
Describe the solution you'd like
Be able to ignore voluntary some constraints
Wish:
pip install Spyder --relax relaxrules.r
, with relax file below meaning:. if you want PyQt5, it must be 5.14.x
. if you want Jedi, it must be >=0.16
Alternative Solutions
Today:
Additional context
Maintaining WinPython
** Current pip check **
** Current workaround **
. PyQt5-5.14.2 (as pip doesn't have a "long term support" of PyQt5-5.12, so the fresher version is safer)
other wishes:
The text was updated successfully, but these errors were encountered: