Why Is Pip Installing an Old Version of My Package

Why is pip installing an old version of my package?

This is an excellent question. It took me forever to figure out. This is the solution that works for me:

Apparently, if pip can find a local version of the package, pip will prefer the local versions to remote ones. I even disconnected my computer from the internet and tried it again -- when pip still installed the package successfully, and didn't even complain, the source was obviously local.

The really confusing part, in my case, was that pip found the newer versions on pypi, reported them, and then went ahead and re-installed the older version anyway ... arggh. Also, it didn't tell me what it was doing, and why.

So how did I solve this problem?

You can get pip to give verbose output using the -v flag ... but one isn't enough. I RTFM-ed the help, which said you can do -v multiple times, up to 3x, for more verbose output. So I did:

pip install -vvv <my_package>

Then I looked through the output. One line caught my eye:

Source in /tmp/pip-build-root/ has version 0.0.11, which satisfies requirement <my_package>

I deleted that directory, after which pip installed the newest version from pypi.

Why is pip installing an older version of this package?

Looking at the package's version history, 0.8.4 is the most current released version, while those newer version are prereleases, and will not be downloaded by default.

Pip does ONLY install old and wrong version of my own package

It seems to me that the current version (0.1.1) requires PIL, which cannot be installed using pip:

pip install sgraphic==0.1.1
Collecting sgraphic==0.1.1
Using cached sgraphic-0.1.1.tar.gz (4.4 kB)
Collecting skia-python
Using cached skia_python-87.2-cp39-cp39-win_amd64.whl (4.3 MB)
Collecting IPython
Using cached ipython-7.27.0-py3-none-any.whl (787 kB)
ERROR: Could not find a version that satisfies the requirement PIL (from sgraphic) (from versions: none)
ERROR: No matching distribution found for PIL

Because pip cannot install all dependencies, it fails to install sgraphic 0.1.1. However, if you do not explicitly request this version, pip will try to find an older version that it can install. Apparently, version 0.0.3 is the latest version it can install, so in your case it did that.

I think this is simply a bug in the latest versions of the sgraphic package. The code contains import PIL, but the package that contains PIL is actually called Pillow. It's also possible that (the original) PIL is supposed to be installed in another way, but I could not find any information about that.

NB: I created an issue on github to ask the author of the package. It was indeed a bug and is now fixed in version 0.1.2, which I could install successfully using pip.

Installing specific package version with pip

TL;DR:

Update as of 2022-12-28:

pip install --force-reinstall -v

For example: pip install --force-reinstall -v "MySQL_python==1.2.2"

What these options mean:

  • --force-reinstall is an option to reinstall all packages even if they are already up-to-date.
  • -v is for verbose. You can combine for even more verbosity (i.e. -vv) up to 3 times (e.g. --force-reinstall -vvv).

Thanks to @Peter for highlighting this (and it seems that the context of the question has broadened given the time when the question was first asked!), the documentation for Python discusses a caveat with using -I, in that it can break your installation if it was installed with a different package manager or if if your package is/was a different version.


Original answer:

  • pip install -Iv (i.e. pip install -Iv MySQL_python==1.2.2)

What these options mean:

  • -I stands for --ignore-installed which will ignore the installed packages, overwriting them.
  • -v is for verbose. You can combine for even more verbosity (i.e. -vv) up to 3 times (e.g. -Ivvv).

For more information, see pip install --help

First, I see two issues with what you're trying to do. Since you already have an installed version, you should either uninstall the current existing driver or use pip install -I MySQL_python==1.2.2

However, you'll soon find out that this doesn't work. If you look at pip's installation log, or if you do a pip install -Iv MySQL_python==1.2.2 you'll find that the PyPI URL link does not work for MySQL_python v1.2.2. You can verify this here: http://pypi.python.org/pypi/MySQL-python/1.2.2

The download link 404s and the fallback URL links are re-directing infinitely due to sourceforge.net's recent upgrade and PyPI's stale URL.

So to properly install the driver, you can follow these steps:

pip uninstall MySQL_python
pip install -Iv http://sourceforge.net/projects/mysql-python/files/mysql-python/1.2.2/MySQL-python-1.2.2.tar.gz/download

Why isn't pip installing the latest version of a package, even when a newer version is on PyPI?

I was trying to upgrade Quart. Maybe other packages have something else going on.

In this particular case, Quart had dropped support for Python 3.6 (the version I had installed) and only supported 3.7 or later. (This was a fairly recent change to the project, so I just didn't see the news.)

However, when attempting to install a package only supported by a later Python, pip doesn't really explain why it couldn't find a version to satisfy the requirement - instead, it just lists all the versions that should work with the current Python, without indicating that more exist and just can't be installed.

The only real options to fix are:

  • Update your Python to meet the package's requirements
  • Ask/help the maintainer to backport the package to the version you have.

pip loop's through previous versions and download them all

just doing the operation as root fixed the problem! (using sudo pip install scikit-learn)
note: according to comments this solution isn't the perfect/safe one!

the proper solution is to just upgrade the pip using pip install --upgrade pip (for now i upgraded to v22.1)

again according to comments and this github issue, the source of this was some conflicts. making the pip testing all previous versions to find the one without conflicts(and it never does).

Resolving new pip backtracking runtime issue

Latest update (2022-02)

There seems to be major update in pip just few days old (version 22.0, release notes + relevant issue on github).

I haven't tested it in more detail but it really seems to me that they optimized installation order calculation in complex case in such way that it resolves many issues we all encountered earlier. But I will need more time to check it.

Anyway, the rest of this answer is still valid and smart requirements pinning suitable for particular project is a good practice imo.


Since I encountered similar issue I agree this is quite annoying. Backtracking might be useful feature but you don't want to wait hours to complete with uncertain success.

I found several option that might help:

  • Use the old resolver (--use-deprecated=legacy-resolver) proposed in the answer by @Daniel Davee, but this is more like temporary solution than a proper one.
  • Skip resolving dependencies with --no-deps option. I would not recommend this generally but in some cases you can have a working set of packages versions although there are some conflicts.
  • Reduce the number of versions pip will try to backtrack and be more strict on package dependencies. This means instead of putting e.g. numpy in my requirements.txt, I could try numpy >= 1.18.0 or be even more strict with numpy == 1.18.0. The strictness might help a lot.

Check the following sources:

  • Fixing conflicts
  • Github pip discussion
  • Reducing backtracking

I still do not have a proper answer that would always help but the best practice for requirements.txt seems to "pin" package versions. I found pip-tools that could help you manage this even with constrains.txt (but I am in an experimental phase so I can not tell you more).

Update (2021-04)

It seems author of the question was able to fix the issue (something with custom gitlab server) but I would like to extend this answer since it might be useful for others.

After reading and trying I ended up with pinning all my package versions to a specific one. This really should be the correct way. Although everything can still work without it, there might be cases where if you don't pin your dependencies, your package manager will silently install a new version (when it's released) with possible bugs or incompatibility (this happens to me with dask last this year).

There are several tools which might help you, I would recommend one of these approaches:

Easiest one with pipreqs

  • pipreqs is a library which generates pip requirements.txt file based on imports of any project
  • you can start by pip install pipreqs and runnning just pipreqs in your project root (or eventually with --force flag if your requirements already exists)
  • it will easily create requirements.txt with pinned versions based on imports in your project and versions taken from your environment
  • then you can at any time create new environment based on this requirements.txt

This is really simple tool (you even do not need to write your requirements.txt). It does not allow you to create something complex (might not be a good choice for bigger projects), last week I found one strange behavior (see this) but generally I'm happy with this tool as it usually works perfectly.

Using pip-tools

There are several other tools commonly used like pip-tools, Pipenv or Poetry. You can read more in Faster Docker builds with pipenv, poetry, or pip-tools or Python Application Dependency Management in 2018 (older but seems still valid to me). And it still seems to me that the best option (although it depends on your project/use case) is pip-tools.

You can (this is one option, see more in docs):

  • create requirements.in (the same format as requirements.txt, it's up to you whether you pin some package dependency or not)
  • then you can use it by pip install pip-tools and running pip-compile requirements.in
  • this will generate new requirements.txt file where all versions are pinned, it's clear, what is the origin
  • (Optionally) you can run it with --generate-hashes option
  • then you can (as with pipreqs) at any time create new environment based on this requirements.txt
  • pip-tools offer you --upgrade option to upgrade the final reqs
  • supports layered requirements (e.g. having dev and prod versions)
  • there is integration with pre-commit
  • offers pip-sync tool to update your environment based on requirements.txt

There are few more stuff you can do with it and I really love the integration with pre-commit. This allows you to use the same requirements as before (just with .in suffix) and add pre-commit hook that automatically updates requirements.txt (so you will never experience having different local environment from the generated requirements.txt which might easily happen when you run something manually).



Related Topics



Leave a reply



Submit