How to pip install a Specific Version of a Package in Python

pip installs a specific version when you put == and the version number after the package name. The same command downgrades or upgrades whatever’s already installed:

python -m pip install tabulate==0.9.0

I tested every command below in a real Windows Command Prompt with Python 3.12.5 and pip 24.2, inside a separate environment so you can see each install happen from scratch.

You’ll also see how to install a version range, find out which versions exist, pin versions in requirements.txt, and install straight from a GitHub tag.

pip install a specific version with ==

== pins an exact version. Here it is going into an environment that doesn’t have the package yet, followed by a check of what got installed:

from importlib.metadata import version

print("tabulate", version("tabulate"))

Command Prompt output:

Collecting tabulate==0.9.0
  Downloading tabulate-0.9.0-py3-none-any.whl.metadata (34 kB)
Downloading tabulate-0.9.0-py3-none-any.whl (35 kB)
Installing collected packages: tabulate
Successfully installed tabulate-0.9.0
tabulate 0.9.0
Command Prompt showing pip install tabulate==0.9.0 downloading and installing that exact version and Python printing tabulate 0.9.0
pip downloaded exactly 0.9.0, and importlib.metadata confirms it.

The long path at the start is just the environment’s own Python. On your machine, python -m pip install tabulate==0.9.0 does the same thing.

I use python -m pip rather than bare pip so the package lands in the Python I’m actually running. ModuleNotFoundError after pip install shows what goes wrong otherwise.

How to downgrade a package with pip

There’s no separate downgrade command. Ask for an older version with ==, and pip uninstalls the newer one first:

python -m pip install tabulate==0.9.0      # from 0.10.0 back to 0.9.0

If pip says the requirement is already satisfied but the package seems broken, add --force-reinstall to install that version again from scratch.

pip install a version range: >=, <, ~= and !=

Often you don’t need one exact version, just one that’s new enough and not too new. Put the range in quotes:

from importlib.metadata import version

print("tabulate", version("tabulate"))

Command Prompt output:

Collecting tabulate<0.11,>=0.10
  Downloading tabulate-0.10.0-py3-none-any.whl.metadata (40 kB)
Downloading tabulate-0.10.0-py3-none-any.whl (39 kB)
Installing collected packages: tabulate
  Attempting uninstall: tabulate
    Found existing installation: tabulate 0.9.0
    Uninstalling tabulate-0.9.0:
      Successfully uninstalled tabulate-0.9.0
Successfully installed tabulate-0.10.0
tabulate 0.10.0
Command Prompt showing pip install tabulate>=0.10,<0.11 in quotes uninstalling 0.9.0 and installing 0.10.0
The range moved tabulate from 0.9.0 to 0.10.0, the newest version below 0.11.
SpecifierMeansExample
==Exactly this versiontabulate==0.9.0
>=, <At least, or below"tabulate>=0.10,<0.11"
~=Compatible release: same minor seriestabulate~=0.9.0 means 0.9.x
!=Anything except this version"tabulate!=0.10.0"
==1.2.*Any patch release of 1.2"tabulate==0.9.*"

Combine conditions with a comma, and always quote anything containing < or >. The next section shows why.

Why pip install package>=version does nothing on Windows

In Command Prompt, > isn’t part of the version: it means “send the output to a file”. So an unquoted range quietly writes pip’s output to a file and installs nothing new:

from importlib.metadata import version

print("tabulate", version("tabulate"))

Command Prompt output:

Requirement already satisfied: tabulate in c:\pyguides\pin_env\lib\site-packages (0.9.0)
tabulate 0.9.0
Command Prompt showing an unquoted pip install tabulate>=0.10 printing nothing, a file named 0.10 holding pip output, and tabulate still at 0.9.0
No output, a new file called 0.10, and tabulate still on 0.9.0.

Command Prompt treated = as a separator, so the file is named 0.10. pip only saw tabulate, which was already installed.

Bash and zsh on macOS and Linux misread > the same way. Wrap the requirement in double quotes and it works everywhere.

How do I see which versions of a package are available?

pip index versions lists every version on PyPI and marks the one you have. It’s still labeled experimental, but it works well:

from importlib.metadata import version

print("tabulate", version("tabulate"))

Command Prompt output:

WARNING: pip index is currently an experimental command. It may be removed/changed in a future release without prior warning.
tabulate (0.10.0)
Available versions: 0.10.0, 0.9.0, 0.8.10, 0.8.9, 0.8.8, 0.8.7, 0.8.6, 0.8.5, 0.8.4, 0.8.3, 0.8.2, 0.8.1, 0.8.0, 0.7.7, 0.7.5, 0.7.4, 0.7.3, 0.7.2, 0.7.1, 0.7, 0.6, 0.5.1, 0.5, 0.4.4, 0.4.3, 0.4.2, 0.3
  INSTALLED: 0.9.0
  LATEST:    0.10.0
ERROR: Invalid requirement: 'tabulate==': Expected end or semicolon (after name and no valid version specifier)
    tabulate==
            ^
Command Prompt showing pip index versions tabulate listing available versions and pip install tabulate== failing with Invalid requirement
The list ends with INSTALLED: 0.9.0. The old tabulate== trick now fails.

You may have seen an older trick: pip install tabulate== with nothing after it, which used to print the versions in its error. Current pip rejects it as an invalid requirement, so use pip index versions instead.

Check which version of a package is installed

Any of these works. The first two run in the terminal, the last one inside your Python code:

python -m pip show tabulate          # the Version: line
python -m pip list                  # every installed package

from importlib.metadata import version
print(version("tabulate"))

Many packages also expose __version__, as checking the pandas version shows, but importlib.metadata works for every installed package.

Pin versions in requirements.txt

For a project, put the versions in requirements.txt so everyone, and every server, installs the same ones:

tabulate==0.9.0

Command Prompt output:

Collecting tabulate==0.9.0 (from -r requirements.txt (line 1))
  Downloading tabulate-0.9.0-py3-none-any.whl.metadata (34 kB)
Downloading tabulate-0.9.0-py3-none-any.whl (35 kB)
Installing collected packages: tabulate
Successfully installed tabulate-0.9.0
tabulate==0.9.0
Command Prompt showing pip install -r requirements.txt installing tabulate 0.9.0 and pip freeze listing tabulate==0.9.0
pip install -r reads the file. pip freeze prints installed versions in the same format.

Running python -m pip freeze > requirements.txt writes your current versions to the file. Do it inside a virtual environment, or you’ll capture every package on your machine.

Install a specific version of a package from GitHub

When a version isn’t on PyPI, or you need an unreleased fix, install from the repository with git+https and pin a tag, branch or commit after @:

python -m pip install "git+https://github.com/astanin/python-tabulate.git@v0.9.0"

# a branch or a commit works the same way
python -m pip install "git+https://github.com/owner/repo.git@main"
python -m pip install "git+https://github.com/owner/repo.git@1a2b3c4"

This needs Git installed. I installed tabulate 0.9.0 from its GitHub tag this way, and it worked; I left out the screenshot only because pip prints a temporary folder from my user profile.

Downloading the same tag as a ZIP archive failed to build, because tabulate works out its version from Git history. If a ZIP install fails like that, switch to git+https.

pip install specific version: quick reference

GoalCommand
Exact versionpython -m pip install tabulate==0.9.0
DowngradeSame as above, with the older version
Rangepython -m pip install "tabulate>=0.10,<0.11"
Reinstall the same versionpython -m pip install --force-reinstall tabulate==0.9.0
See available versionspython -m pip index versions tabulate
See the installed versionpython -m pip show tabulate
From a filepython -m pip install -r requirements.txt
From a GitHub tagpython -m pip install "git+https://github.com/owner/repo.git@v1.0"

Related guides on installing and checking Python packages:

Frequently asked questions

How do I install a specific version of a package with pip?

Use ==: python -m pip install tabulate==0.9.0. If a different version is installed, pip replaces it.

How do I downgrade a package with pip?