Skip to content

Relaxing / Ignoring constraints during dependency resolution #8076

Description

@stonebig

What's the problem this feature will solve?
Puting together some packages that have by default incompatible constraints.

Indeed:

  • constraints are often meant by the package maintainer as:
    . "accepting complains on this known/focus set of package",
    . you're on your own support if you deviate, but not necessarly bad.
  • packages rarely focus on the same versions of complementary packages.
    ==> 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:

  • we can put some "relax" rule to over-rule too strict packages (for our need), because we know what we want:
    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
PyQt5~=5.14
Jedi>=0.16

Alternative Solutions
Today:

  • I have to manually recompile from source "too strict" packages, to workaround this,
  • or I would have to build one virtualenv per package,
  • or I would only be able to use a specific Python distribution, with much older packages and Python version.

Additional context
Maintaining WinPython

** Current pip check **

  • datasette 0.39 has requirement Jinja2~=2.10.3, but you have jinja2 2.11.2.
  • astroid 2.3.3 has requirement wrapt==1.11.*, but you have wrapt 1.12.1.

** Current workaround **

  • Spyder manually recompiled to accept :
    . 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:

  • a basic GUI on Pip (tkinter or web) would still be nice, to have a better view of all the coming version conflicts.

Activity

  1. ghost added
    S: needs triageIssues/PRs that need to be triaged
    on Apr 18, 2020
  2. changed the title [-]a --whitelist feature for the New resolver ? a pipdeptree like description of dependancies ? a gui over that?[/-] [+]a --whitelist feature for the New resolver ? a pipdeptree-like description of dependancies ? a gui over that?[/+] on Apr 18, 2020
  3. changed the title [-]a --whitelist feature for the New resolver ? a pipdeptree-like description of dependancies ? a gui over that?[/-] [+]a --relax feature for the New resolver ? a pipdeptree-like description of dependancies ? a gui over that?[/+] on Apr 18, 2020
  4. uranusjr commented on Apr 18, 2020

    @uranusjr
    Member

    @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.

  5. stonebig commented on Apr 18, 2020

    @stonebig
    ContributorAuthor

    Ok, separating other whishes in a few minutes.
    this is moved on another issue:

    - having the beautifull "pipdeptree" features in the standard pip:
        . a beautifull description of what package needs (or is needed) by what package of what version,
        . the possibility to get that programatically as json answers.
    
  6. ghost removed
    S: needs triageIssues/PRs that need to be triaged
    on Apr 18, 2020
  7. ghost removed
    S: needs triageIssues/PRs that need to be triaged
    on Apr 18, 2020
  8. changed the title [-]a --relax feature for the New resolver ? a pipdeptree-like description of dependancies ? a gui over that?[/-] [+]Relaxing / Ignoring constraints during dependnecy resolution[/+] on Apr 18, 2020
  9. changed the title [-]Relaxing / Ignoring constraints during dependnecy resolution[/-] [+]Relaxing / Ignoring constraints during dependency resolution[/+] on Apr 18, 2020
  10. pradyunsg commented on Apr 18, 2020

    @pradyunsg
    Member

    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.

  11. pradyunsg commented on Apr 18, 2020

    @pradyunsg
    Member

    a basic GUI on Pip (tkinter or web) would still be nice, to have a better view of all the coming version conflicts.

    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. :)

  12. stonebig commented on Apr 18, 2020

    @stonebig
    Author
  13. stonebig commented on Apr 19, 2020

    @stonebig
    ContributorAuthor

    Building a dsitribution WinPython is quite simple:

    • download in a dedicated directory all the wheels (and version) you want,
    • then pip install -r requirement.txt
    • then one by one, try to fix all the problems:
      • missing wheels,
        • pip download --dest,
        • or cgohlke site of wonders
        • or github/gitlab (/pip-forge one day ?)
      • non-existing wheels,
        • do-compile-yourself (often fails, like for cartopy, or for Python-recent version)
        • raise issues to package maintainer
      • wheels whose beloved version of dependancies mutualy contradicts
        • ask maintainer to relax or upgrade his/her dependancies (very slow process)
        • recompile it yourself without the annoying constraint,
        • go back in version to an older one (with potential security or known issues fixed since ages)
        • or drop the wheel.

    I dream of a way to reverse the problem:

    • showing package maintainer how their 'too restrictive' constraints makes them incompatible with the rest of the world, (hence a GUI or a pypi website feature ?):
      • give your requirements.txt
      • precise your "beloved" package,
      • the site/gui tells you what fits / what contradicts / what downgrade your package imposes
    • or do a third kind of constraints on dependancies in wheel specification:
      • supported constraints (you can speak of a problem to the maintainers when you have this "set"),
      • a "support_requires" next to "install_requires" and "extra_requires" ?
  14. 121 remaining items

  15. PiotrDabkowski commented on Aug 17, 2022

    @PiotrDabkowski

    +1
    Very often the project will still work, even if the exact dependency version is different.

    We already have the great constraints file, where we can manually specify version of dependencies (-c option). Can we add an option to for constraints to override the package-specified version, eg --force-constraints? So similar to @notatallshaw proposal, but reusing the existing constraint infra.

    For example, assume that package A requires numpy==1.23 and package B requires numpy<1.20. Even if we find that package B works well with Numpy 1.23 (at least for the set of features that we care about), we will have a hard time installing things with pip, we would need to use workarounds like --no-deps, and manually installing deps later.

    With --force-constraints option we would simply specify a constraint numpy==1.23 and we are good, a warning can still be logged during installation, that the dependency version has been overwritten by the const.

    Implementation would be super simple - just override the dependency version requirement if it conflicts with the constraint, and log a warning.

  16. balloob commented on Oct 6, 2022

    @balloob
    Contributor

    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.

  17. mauritsvanrees commented on Nov 1, 2022

    @mauritsvanrees
    SponsorContributor

    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)
    Let me post the todo items from there.

    1. Confirmation from others in the issue that this indeed fixes their problem. I will add a comment there pointing to this PR.
    2. A decision on the format: extend the constraints syntax with -o like in this PR, or use a separate overrides file with strictly limited formatting. Looks like the discussion is leaning towards the last.
    3. tests
    4. documentation

    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.

  18. FRidh commented on Jan 15, 2023

    @FRidh

    @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, =o, so mypkg =o 0.1.5 to override all constraints and set a version (or set no version), but this might warrant a PEP; we definitely would not want individual packages to use this operator.

  19. pradyunsg commented on Jul 18, 2023

    @pradyunsg
    Member

    In #9948, we're discussing adding a per-requirement --no-deps to allow users to opt-out of dependency handling for certain entries in a requirements.txt file. While that doesn't solve the "relaxing" part of the request here, it does provide ignoring functionality -- in a highly pip-specific manner.

    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.

  20. pfmoore commented on Jul 18, 2023

    @pfmoore
    Member

    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 "pip install foo fails with an error". No-one can reproduce the issue locally. After much investigation, it turns out that the user is installing into an existing environment that has a horribly broken mess of pre-installed packages, including a number of packages deep in the dependency tree of foo. But the user has done nothing but use supported pip features (like this one) to create that environment.

    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 pip check shows that their environment is clean. But do we want to offer tools that make it easier for users to get into that situation in the first place? There's still a maintenance cost involved, as we sometimes spend time trying to understand the user's problem before we get round to asking the "obvious questions".

    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 --break-system-packages, it fixes your issue"... 🙁) who could easily find something like this a big footgun.

  21. gst commented on Jul 18, 2023

    @gst

    Are we willing to support people using pip in already-broken environments?

    by broken do you mean pip check fails ? I guess..

    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).

    After much investigation, it turns out that the user is installing into an existing environment that has a horribly broken mess of pre-installed packages,

    I would guess/hope that someone would ask to pip list or pip check the given user installation/environment. Or simply/directly request him to try with fresh/clean python (v)environment too.

  22. pfmoore commented on Jul 18, 2023

    @pfmoore
    Member

    isn't it already the case ipso-facto (that pip running/installing in already "broken" env is allowed/supported) ?

    No. There are many reasons why pip doesn't run pip check before allowing an install, but that doesn't mean that it's supported. Think of it like "undefined behaviour". You can do it, and it might allow you do achieve some really neat goal, but that doesn't mean you can rely on it. Unless we (the pip maintainers) decide between us that we want to support it, in the sense of applying our stability and backward compatibility policies to it, for example.

    I would guess/hope that someone would ask to pip list or pip check the given user installation/environment.

    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 pip check", with the implication that if it reports problems, we'll say "that's your issue, fix that and you'll be fine"?

  23. mauritsvanrees commented on Jul 18, 2023

    @mauritsvanrees
    SponsorContributor

    If a pip environment is already broken, people may need tools to unbreak it. At the minimum, if pip check currently fails, pip install should still work, otherwise you have no other option but to throw away your environment.

    I think it should work like this, and I have no idea if that is the case now:

    • pip install good combination -> works
    • pip check -> passes
    • pip install bad combination: does pip check after analysing the dependencies, which fails, so the installation is stopped before anything is actually installed.
    • Now somehow break the environment.
    • pip check -> fails
    • pip install another good combination -> This should work. Yes, pip check fails after analysing the dependencies, but it should realise that pip check already fails in the current environment, so pip install should continue, as the user may be trying a first step to unbreak the environment.

    That said: I think it is fair to update the bug report issue template to ask people to include the output of pip check.

  24. pfmoore commented on Jul 18, 2023

    @pfmoore
    Member

    It's a while since I checked the details, but from what I recall, pip install runs a pip check when it's complete, and reports if there is an issue. At that point, pip uninstall and pip install still work fine. We don't ever fail because of a broken environment, you're just in "you broke it, you get to fix it" territory.

    There are plenty of ways you can use documented pip features to break an environment. The obvious trivial one is pip install --no-deps A when A depends on B. Or pip install A; pip uninstall B. But that doesn't (IMO) mean we're under an obligation to do anything sane when working with that environment (it's hard even to be sure what "sane" means!) I think you can reasonably expect that pip uninstall and pip install --no-deps work. Beyond that, by all means give it a go, but you may hit issues. I think you'll find that plenty more than that will work reasonably well, but I'm not guaranteeing anything.

    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.

  25. notatallshaw commented on Feb 16, 2024

    @notatallshaw
    Member

    Small update for anyone who needs this feature, uv has a pip-like install interface and supports a --override flag.

    I will also make the observation it reads almost exactly as though someone implemented what I proposed here, so we may get real world data on if that was a good proposal or not.

  26. stonebig commented on Feb 17, 2024

    @stonebig
    ContributorAuthor

    Interesting, at least for the:

    • speed,
    • compatibility aim with pypa,
    • carbon footprint
    • extra.

    Adding the pipdeptree style features would be great, especially if accessible by api/not using the command line

  27. JalinWang commented on May 15, 2025

    @JalinWang

    Small update for anyone who needs this feature, uv has a pip-like install interface and supports a --override flag.

    uv pip interface has a useful behavior when dealing with conflicting dependencies. If packages a and b have incompatible dependencies, running uv pip install a b will fail due to the conflict. However, installing them one by one (uv pip install a, then uv pip install b) will incur automatically uninstalling or upgrading conflicting versions. This makes it available to manually adjust/override dependencies — meanwhile pip just refuses me again and again :(

    This seems to be an old pip behavior and sometime can lead to problems. But a flag ( e.g., --ignore-conflicts ) to enbale this behavior manually definitely helps a lot when encountering such a situtation.

    Image

  28. notatallshaw commented on May 15, 2025

    @notatallshaw
    Member

    If packages a and b have incompatible dependencies, running uv pip install a b will fail due to the conflict. However, installing them one by one (uv pip install a, then uv pip install b) will incur automatically uninstalling or upgrading conflicting versions. This makes it available to manually adjust/override dependencies

    This behavior was copied from pip, although the exact resolution might not be the same between pip and uv pip you should see the same general behavior.

    meanwhile pip just refuses me again and again :(

    This seems to be an old pip behavior and sometime can lead to problems. But a flag ( e.g., --ignore-conflicts ) to enbale this behavior manually definitely helps a lot when encountering such a situtation.

    I'm not sure what you mean, uv doesn't ignore the conflicts of a given install request, same as pip, maybe you're looking for the --upgrade flag which eagerly upgrades rather than trying to keep the version installed?

    If you have a specific problem where pip install a followed by pip install b refuses to install and you think it should then please create a new issue with a reproducible example.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions