Can I prevent pip from downgrading packages implicitly?
Asked Answered
B

2

16

I have Django 1.10.5 installed in my python virtual environment.

When I install djblets into my virtualenv with pip install djblets, unfortunately, Django is being implicitly downgraded to version 1.8.17 along the way. This breaks my environment.

Is there something I could have done to prevent this? I certainly wasn't asked whether I'm okay with the downgrade. But I really should have.

djblets version 0.9.6 doesn't even install because it depends on Pillow, which refuses to build. It's all just broken and kills my environment along the way because uninstalling comes first.

All I can think about is trying the installation in a separate, but identical, virtual environment and seeing what happens. Like a dry-run.

Now I have to install my environment from scratch. Am I missing something, or is this just the way it is?

Babylonian answered 30/3, 2017 at 14:39 Comment(0)
D
7

Actually there is in newer (ok, since long long ago, pip 7.1) pip versions, although it's not exactly documented like that:

Pip constraint files

So the following commands (you need to run them in your project directory and potentially customize them):

pip freeze | grep == | sed 's/==/>=/' >constraints.txt
pip install -c constraints.txt whatever-you-want-to-install

will install whatever-you-want-to-install without downgrading anything. Caveat: whatever-you-want-to-install actually requires a lower version "sometoy", whatever-you-want-to-install will be broken, at least in relation to it's usage of "sometoy".

In some cases the breakage might be acceptable (e.g. it happens in some optional areas of the package that you do not use), in some cases no actual breakage might happen (e.g. the downgrade causing version constraint is not needed anymore), in some cases really bad things will happen and they are on you.

Delegate answered 17/6, 2020 at 9:26 Comment(2)
isn't sed alone necessary without grep?Existent
Well, sed alone would have a different meaning. grep selects the packages that have a specific version selected only. OTOH, it's possible that sed can be used to "grep" out only some lines too, but then I prefer to use the simplest tool at hand. Another CAVEAT: pip has changed fundamentally its behaviour since Oct/Nov 2020. so take care with anything you read here.Delegate
K
2

You need to install both packages at the same time (with only one command) and specify the number version of the package

pip install django==1.10.5 djblets

As a rule of thumb, rather than installing your packages one-by-one, I'd recommand using a requirements.txt file.

For your example, your file requirements.txt will have (at least):

django==1.10.5
djblets==1.0.2

Then, you can install all packages in one time using the option [--requirements, -r] of pip:

pip install -r requirements.txt

Why?

Unless told excplicitly so, pip will try to install the best dependencies for a given module (the ones describe in the package itself) and that could even downgrade a package!

Oftentimes, you will not have a choice to downgrade NOR upgrade a package to make it work. That's why it is very important to put a version number in each packages you need in order to avoid regression!

Tips

(OK because update option works only with packages having unspecified version number)

  • You can also install a package with no dependencies at all with option [--no-deps] of pip:

    pip install --no-deps djblets
    

But this method is only valid if you have already all the dependencies installed.

Bonus

To answer the question you did not ask, you can make a "snapshot" of all your packages install if you are scared of doing wrong manipulations, using pip freeze

pip freeze > requirements.txt
Kristoforo answered 24/1, 2018 at 22:34 Comment(2)
If djblets depends on django==1.8.17, this will probably break djblets because django==1.10.5 will be forcibly installed. There isn't any solution to this specific problem besides having both your code and djblets work on a single version of Django.Maclaine
@Maclaine yes I totaly agree with you! To be honest I did not even tried to installed both packages because I'm not currently with my "dev-pc". It just happend that I had downgrading problems with pip today at work that I was able to fix using this technique (it was a chaining several requirements.txt files, but it is similar). Anyhow: I just wanted to have a "generic solution" for this kind of problems. Because I did not found any on SO. Even if it didn't solve this very problem, I think it could be useful to other peoples. But maybe I should have created my own question. Nice remark though.Firn

© 2022 - 2025 — McMap. All rights reserved.