How to Check Python Module Version: The Definitive Guide for Senior Engineers

pip show failing? Here are 3 quick commands to check any Python package version: pip freeze, pip list, and inline Python. Copy-paste ready.

Python powers everything from quick automation scripts to production-grade machine learning pipelines. When something breaks in production but works perfectly on your laptop, the culprit is almost always a version mismatch. I have seen production incidents traced back to a single package being one patch version behind where it needed to be. The ability to quickly and accurately check Python module versions is not a nice-to-have skill. It is a core part of every Python engineer’s daily workflow.

This article covers every practical method for checking Python package versions, from a single terminal command to programmatic checks inside your code. I walk through pip show, pip list, importlib.metadata, and __version__ attributes. I explain when to use each approach, what the common mistakes are, and how to integrate version checking into CI/CD pipelines. By the end you will have a complete mental model for managing Python package versions in any environment you work in.

TL;DR

  • Quick check: Run pip show for detailed info on any package
  • Programmatic approach: Use importlib.metadata.version('package') inside Python code
  • Overview all packages: Run pip list to see every installed package and version
  • Export for sharing: Run pip freeze > requirements.txt to capture exact versions
  • Python 3.8+ only: Use the importlib.metadata standard library, not pkg_resources

pip show vs pip list vs importlib.metadata: Complete Comparison

Method Best For Scope Output Type Availability
pip show Detailed info on one specific package Single package Formatted metadata (name, version, location, deps) Any Python with pip
pip list Quick overview of entire environment All packages Simple two-column list (name + version) Any Python with pip
pip freeze Generating requirements.txt files All packages Name==Version format (pip-installable) Any Python with pip
importlib.metadata Programmatic version checks inside code Single or all packages Python strings and objects Python 3.8+ (stdlib)
__version__ attribute Quick one-liners for packages that support it Single package String version Only packages that define it

Why Does Checking Python Module Versions Matter in Production?

Every senior engineer has been there. You ship code to production and it breaks because the deployment environment has a different package version than your local machine. The requests library changed an API between 2.28 and 2.31. NumPy dropped support for a deprecated array creation function. Your CI passed but production fails.

Version mismatches are among the top causes of production incidents in Python applications. When you have dozens of direct dependencies and hundreds of transitive dependencies, tracking what version is where becomes a full-time job. The tools I am about to show you are the first line of defense.

Beyond incident prevention, version checking matters for security. The requests library alone has had multiple CVEs fixed in point releases. If you do not know what version you are running, you cannot know if you are exposed. Running pip list --outdated periodically is not paranoia. It is standard engineering practice.

Dependency confusion attacks are another reason to verify versions. An attacker publishes a malicious package with the same name as an internal package to a public index. If your environment resolves to the wrong version, you have a supply chain problem. Knowing exactly which version you have installed is the foundation of defending against this class of attack.

How Do I Check a Specific Package Version with pip show?

The most direct way to get detailed information about a single package is pip show. Run it from your terminal with the package name and you get everything: version, home page, author, license, installation location, direct dependencies, and which other packages depend on it.

Here is the command:

pip show 

For example, to check the requests library:

pip show requests

The output looks like this:

Name: requests
Version: 2.31.0
Summary: Python HTTP for Humans.
Home-page: https://requests.readthedocs.io
Author: Kenneth Reitz
Author-email: [email protected]
License: Apache 2.0
Location: /usr/local/lib/python3.11/site-packages
Requires: charset-normalizer, idna, urllib3, certifi
Required-by: botocore, boto3

Notice that the output tells you not just the version but also what requests requires and what depends on it. That Required-by field is useful when you are trying to figure out why a package is installed at all.

If you want just the version number and nothing else, pipe the output through grep or awk:

pip show requests | grep Version
# Or on Unix:
pip show requests | awk '/Version:/ {print $2}'

On Windows, you can use findstr:

pip show requests | findstr Version

For CI/CD pipelines where you need to validate versions programmatically, use the --format=json flag (pip 22.0+):

pip show requests --format=json

This gives you a JSON object you can parse in any language:

{
    "name": "requests",
    "version": "2.31.0",
    "summary": "Python HTTP for Humans.",
    "home_page": "https://requests.readthedocs.io",
    "author": "Kenneth Reitz",
    "author_email": "[email protected]",
    "license": "Apache 2.0",
    "location": "/usr/local/lib/python3.11/site-packages",
    "requires": ["charset-normalizer", "idna", "urllib3", "certifi"],
    "required_by": ["botocore", "boto3"]
}

How Do I Check All Installed Package Versions at Once?

Sometimes you need the full picture. pip list shows every package installed in the current environment in a simple two-column format:

pip list

The output looks like this:

Package         Version
--------------- ---------
pip             24.0
setuptools      69.5.1
wheel           0.43.0
requests        2.31.0
numpy           1.26.3
pandas          2.1.4

If you are working in a virtual environment, pip list only shows packages in that environment. That is exactly what you want. Never check versions in the wrong environment.

To find outdated packages, use the --outdated flag. This is the command I run every morning before touching any codebase:

pip list --outdated

To get output in a format suitable for requirements.txt, use pip freeze:

pip freeze

This gives you output in package==version format that you can redirect to a file:

pip freeze > requirements.txt

You can then install exact versions in a fresh environment with:

pip install -r requirements.txt

Note that pip freeze includes every package pip knows about, including pip itself and setuptools. Often you want only direct dependencies. Use pipreqs or pip-chill for that:

pip install pip-chill
pip-chill

How Do I Check Python Package Versions Inside My Code?

There are cases where you need to check a package version from within Python code itself. Maybe you are building a library that needs to behave differently depending on the NumPy version. Maybe you are writing a setup script that validates the environment before proceeding. For these cases, importlib.metadata is the right tool.

For Python 3.8 and newer, the standard library includes importlib.metadata. It reads package metadata from the .dist-info directories that pip creates when installing packages:

from importlib.metadata import version

requests_version = version('requests')
print(f"Requests version: {requests_version}")

The version() function returns the version as a string. It is simple and reliable:

from importlib.metadata import version

packages = ['requests', 'numpy', 'pandas', 'django', 'flask']
for pkg in packages:
    try:
        ver = version(pkg)
        print(f"{pkg}=={ver}")
    except Exception as e:
        print(f"{pkg}: not found ({e})")

To list all installed packages programmatically, use the distributions() function:

from importlib.metadata import distributions

for dist in distributions():
    name = dist.metadata['Name']
    ver = dist.version
    print(f"{name}=={ver}")

This is equivalent to pip freeze but gives you Python objects you can filter, sort, or serialize as needed.

For Python 3.7 and earlier, importlib.metadata is not in the standard library. You have two options. The first is to use the backport:

pip install importlib-metadata
from importlib_metadata import version

ver = version('requests')
print(f"Requests version: {ver}")

The second option is to fall back to the older pkg_resources module from setuptools:

import pkg_resources

requests_version = pkg_resources.get_distribution('requests').version
print(f"Requests version: {requests_version}")

That said, pkg_resources is deprecated and slower. If at all possible, upgrade to Python 3.8 or newer and use importlib.metadata.

What About the __version__ Attribute? Does That Still Work?

Many Python packages expose a __version__ attribute on the module. NumPy does it, Django does it, many others too:

import numpy as np
print(np.__version__)
# Output: 1.26.3

import django
print(django.__version__)
# Output: 5.0.1

import requests
print(requests.__version__)
# Output: 2.31.0

This approach works but it is a convention, not a standard. Some packages use __version__, others use VERSION, others use version as a module-level constant. Some packages do not expose a version attribute at all.

If you are writing a library that needs to check the version of a dependency, importlib.metadata.version() is more reliable than trying to access __version__. It handles the inconsistencies across packages. Here is why:

# Unreliable - package might not have __version__
import somelib
print(somelib.__version__)  # AttributeError if not defined

# Reliable - always works if package is installed
from importlib.metadata import version, PackageNotFoundError
try:
    ver = version('somelib')
    print(ver)
except PackageNotFoundError:
    print("somelib is not installed")

The importlib.metadata approach is also faster because it reads metadata from the installed package files rather than importing the entire module.

How Do I Check Python Module Version for Popular Packages?

Let me give you concrete examples for the packages I see most often in production environments.

NumPy

# Command line
pip show numpy

# Inside Python
from importlib.metadata import version
print(version('numpy'))

# Module attribute
import numpy as np
print(np.__version__)

All three approaches give the same result. The importlib.metadata approach is what I recommend for scripts because it does not require importing the entire NumPy library just to check a version string.

Pandas

# Command line
pip show pandas

# Inside Python
from importlib.metadata import version
print(version('pandas'))

# Module attribute
import pandas as pd
print(pd.__version__)

Django

# Command line
pip show django

# Inside Python
from importlib.metadata import version
print(version('django'))

# Module attribute
import django
print(django.__version__)

Requests

# Command line
pip show requests

# Inside Python
from importlib.metadata import version
print(version('requests'))

# Module attribute
import requests
print(requests.__version__)

TensorFlow

# Command line
pip show tensorflow

# Inside Python
from importlib.metadata import version
print(version('tensorflow'))

# Module attribute
import tensorflow as tf
print(tf.__version__)

PyTorch

# Command line
pip show torch

# Inside Python
from importlib.metadata import version
print(version('torch'))

# Module attribute
import torch
print(torch.__version__)

How Do I Check Python Module Version in Different Environments?

Virtual Environments

Always check versions in the correct virtual environment. Activate your environment first, then run pip commands. The version you see depends entirely on which environment is active:

# Create and activate
python -m venv myenv
source myenv/bin/activate  # Linux/Mac
# myenv\Scriptsctivate   # Windows

# Now check versions
pip show numpy

If you see unexpected versions, verify your environment is active. Run which python (Unix) or where python (Windows) to confirm which interpreter you are using.

Docker Containers

Inside a Docker container, the workflow is the same. Build your image, run a container, activate the environment if applicable, then check versions:

docker run -it myimage /bin/bash
source /venv/bin/activate
pip show numpy

For a one-liner without shell access:

docker exec mycontainer pip show numpy

Jupyter Notebooks

Jupyter has its own kernel and its own environment. If you are running Jupyter inside a virtual environment, pip show from a terminal might show different results than running importlib.metadata inside a notebook cell. Always check from within the notebook kernel you are actually using:

# In a Jupyter cell
from importlib.metadata import version
print(version('numpy'))
print(version('pandas'))

CI/CD Pipelines

In GitHub Actions, GitLab CI, or similar, always validate versions as part of your pipeline to catch environment drift:

# In a CI job
- name: Check critical package versions
  run: |
    pip show numpy | grep Version
    pip show pandas | grep Version
    pip show django | grep Version

You can also use a Python script in your CI to validate against a known-good version:

from importlib.metadata import version
import sys

required = {
    'numpy': '1.26.0',
    'pandas': '2.1.0',
}

for pkg, min_ver in required.items():
    installed = version(pkg)
    if installed < min_ver:
        print(f"FAIL: {pkg} {installed} < {min_ver}")
        sys.exit(1)
    print(f"OK: {pkg} {installed}")

What Are the Most Common Mistakes When Checking Python Package Versions?

Mistake 1: Checking the wrong environment

The most common mistake is running pip show in one environment but importing in another. Python always uses the interpreter that runs the code. If you have multiple Python installations or virtual environments, they have independent package stores. Always verify which environment you are in:

# Always do this first
import sys
print(sys.executable)
print(sys.prefix)

Mistake 2: Relying on __version__ without fallback

The __version__ attribute is not guaranteed to exist. Packages change their attributes, some packages use different names, and some packages do not expose version at the module level at all. Always handle the missing case:

import somelib

# This will crash if __version__ is not defined
# print(somelib.__version__)

# Safer approach using importlib.metadata
from importlib.metadata import version, PackageNotFoundError
try:
    print(version('somelib'))
except PackageNotFoundError:
    print("somelib not installed")

Mistake 3: Using pkg_resources in new code

The pkg_resources module from setuptools is deprecated. It is slow because it scans the entire environment on import. importlib.metadata is faster, is part of the standard library, and is the future. Migrate any old code that uses pkg_resources:

# Old (deprecated)
import pkg_resources
ver = pkg_resources.get_distribution('requests').version

# New (standard library)
from importlib.metadata import version
ver = version('requests')

Mistake 4: Forgetting that pip list shows ALL packages

pip list shows every package pip knows about, including pip itself, setuptools, wheel, and any other packages that came with your Python distribution. When generating requirements.txt, you usually want only your application dependencies. Use pip-chill or manually filter the output:

# Only top-level dependencies, not transitive ones
pip-chill --no-chill

How Do I Verify Python Module Version in Requirements Files?

Requirements files are static snapshots of your environment at a point in time. Over time, the packages listed in a requirements.txt may drift from what is actually installed. Here is how to audit the gap:

# Generate current freeze
pip freeze > current.txt

# Compare with your requirements
diff requirements.txt current.txt

For a more structured approach, use pip-tools:

# Install pip-tools
pip install pip-tools

# Generate a locked requirements file
pip-compile requirements.in

# This creates requirements.txt with pinned versions
# that satisfy all constraints in requirements.in

For checking specific package versions against requirements:

# Check if numpy is at least version 1.26
from importlib.metadata import version
from packaging import version as pkg_version

installed = version('numpy')
required = '1.26.0'

if pkg_version.parse(installed) < pkg_version.parse(required):
    print(f"FAIL: numpy {installed} < required {required}")
else:
    print(f"OK: numpy {installed}")

The packaging library handles version comparison correctly, accounting for pre-releases, dev releases, and post-releases in a way that string comparison cannot.

Quick Reference: Python Module Version Check Commands

Task Command Notes
Check specific package (terminal) pip show Full metadata output
Check specific package (terminal, version only) pip show | grep Version Quick one-liner
List all packages (terminal) pip list Two-column output
Find outdated packages (terminal) pip list --outdated Useful for maintenance
Generate requirements file (terminal) pip freeze > requirements.txt Exact version pins
Check version in Python code importlib.metadata.version('name') Python 3.8+
Check via module attribute import pkg; print(pkg.__version__) Only if package defines it
List all packages in Python importlib.metadata.distributions() Programmatic equivalent of pip freeze

How do I check the version of a specific Python module?

Run pip show <module-name> from your terminal for full metadata including version, author, license, and dependencies. Alternatively, use import importlib.metadata; print(importlib.metadata.version('module-name')) inside any Python script. Both approaches work reliably for every package installed via pip, and neither requires you to import the package itself.

What is the difference between pip list and pip freeze?

pip list displays all installed packages in a simple two-column table showing name and version. pip freeze outputs packages in name==version format that you can redirect directly into a requirements.txt file for environment recreation. Use pip list for quick human-readable overviews. Use pip freeze when you need to capture exact versions for sharing or deployment.

Which Python version introduced importlib.metadata?

importlib.metadata entered the Python standard library in Python 3.8. For Python 3.7 and earlier, the backport package importlib-metadata provides the same API via pip install importlib-metadata and then from importlib_metadata import version. If you are on Python 3.8 or newer, always use the standard library version.

Why does pip show give a different version than the __version__ attribute?

Both should return the same version string for correctly installed packages. If they differ, you are almost certainly looking at different environments. The terminal where you run pip show and the Python interpreter running your code must be the same installation. Run import sys; print(sys.executable) inside your code and compare it to the python path your terminal uses to confirm they match.

How do I check all installed package versions at once in Python?

Use importlib.metadata.distributions() to iterate over all installed packages and read their metadata. This is the fully programmatic equivalent of pip freeze, returning Python objects you can filter, sort, or serialize as needed. Unlike calling pip as a subprocess, this works entirely inside Python without spawning a new process.

How do I find which packages are outdated in my Python environment?

Run pip list --outdated from your terminal. This prints every package where a newer version exists on PyPI, showing the installed version and the latest available version. I recommend running this weekly in any production environment. For automated vulnerability scanning on top of this, install and run pip-audit which cross-references your packages against the Python Packaging Advisory Database.

Should I use __version__ or importlib.metadata for checking versions in my code?

Always prefer importlib.metadata.version() over the __version__ attribute. The __version__ attribute is a convention that some packages implement inconsistently or not at all. Some packages use VERSION, others use version, and some define it differently across modules. importlib.metadata reads the official package metadata that pip stores at installation time, which is standardized and reliable regardless of how the package author structured their module.

How do I check Python package versions inside Docker containers?

You have two options. The interactive approach uses docker exec to run pip commands inside a running container: docker exec mycontainer pip show numpy | grep Version. For containers not yet built or running, add version checks directly in your Dockerfile with RUN pip show numpy | grep Version and similar commands. When building images, always pin your Python version and your package versions in your requirements.txt to ensure every container build produces the same environment.

Internal Links

Aditya Gupta
Aditya Gupta
Articles: 500