How To Check The Version Of A Python Package

9 min read

Knowing exactly which version of a Python package is installed in your environment is a fundamental skill for every developer. Whether you are debugging a compatibility issue, replicating a production environment, or writing a requirements.txt file for deployment, the ability to check the version of a Python package quickly and accurately saves hours of troubleshooting. This guide covers every reliable method—from command-line tools to programmatic inspection—ensuring you have the right technique for any situation And that's really what it comes down to..

Why Checking Package Versions Matters

Before diving into the commands, it helps to understand why this task is so frequent in a developer's workflow. Consider this: python’s ecosystem relies heavily on semantic versioning (SemVer). A minor update might introduce a new feature you need, while a major update could break your existing code due to deprecated APIs It's one of those things that adds up..

Easier said than done, but still worth knowing.

Common scenarios include:

  • Dependency Conflicts: Two libraries require different versions of the same dependency.
  • Reproducibility: Pinning exact versions in requirements.Practically speaking, txt or pyproject. toml ensures your team and CI/CD pipeline run identical code. In real terms, * Security Auditing: Verifying you have patched versions for known vulnerabilities (CVEs). * Feature Availability: Confirming a specific function or class exists in your installed version before writing code that uses it.

Method 1: Using the Command Line (Terminal/Shell)

The fastest way to check a version without opening a Python interpreter is via the shell. This is ideal for quick checks during development or inside CI/CD scripts Less friction, more output..

Using pip show

The most informative command is pip show. It displays metadata including version, location, installer, and dependencies.

pip show requests

Output example:

Name: requests
Version: 2.31.0
Summary: Python HTTP for Humans.
Home-page: https://requests.readthedocs.io
Author: Kenneth Reitz
Author-email: me@kennethreitz.org
License: Apache 2.0
Location: /home/user/.local/lib/python3.11/site-packages
Requires: charset-normalizer, idna, urllib3, certifi
Required-by: 

Pro Tip: If you only want the version number (useful for scripting), combine it with grep (Linux/macOS) or findstr (Windows):

# Linux / macOS
pip show requests | grep Version

# Windows (Command Prompt)
pip show requests | findstr Version

# Windows (PowerShell)
pip show requests | Select-String Version

Using pip list or pip freeze

If you need to check multiple packages or generate a snapshot of the entire environment:

  • pip list: Returns a formatted table of all installed packages. Great for human readability.
  • pip freeze: Outputs in requirements.txt format (package==version). This is the standard for freezing dependencies.
pip list | grep pandas
# Output: pandas          2.1.4

pip freeze | grep numpy
# Output: numpy==1.26.2

Using python -m pip

Best practice dictates using python -m pip instead of calling pip directly. This guarantees you are using the pip associated with the specific Python interpreter you are targeting, avoiding the common "wrong environment" pitfall.

python -m pip show django
python3 -m pip list

Method 2: Programmatic Checks (Inside a Python Script)

Often, you need to check a version inside your application code—for example, to enable conditional logic based on library features or to log the environment state at runtime.

The Modern Standard: importlib.metadata (Python 3.8+)

Since Python 3.This is the recommended, zero-dependency way to inspect installed distributions. Here's the thing — metadata. 8, the standard library includes importlib.It is fast because it reads metadata files directly without importing the package code itself.

from importlib.metadata import version, PackageNotFoundError

def get_package_version(package_name: str) -> str:
    try:
        return version(package_name)
    except PackageNotFoundError:
        return "Not installed"

print(f"Requests version: {get_package_version('requests')}")
print(f"Non-existent version: {get_package_version('this-package-does-not-exist')}")

Why prefer this?

  1. No Import Side Effects: It does not execute the package's __init__.py. This avoids triggering heavy imports, registration logic, or potential errors if the package is broken.
  2. Standard Library: No external dependencies required for Python 3.8+.
  3. Handles Namespaces: Works correctly with namespace packages.

The Legacy Standard: pkg_resources (setuptools)

For projects stuck on Python 3.Practically speaking, 7 or older, pkg_resources (part of setuptools) was the go-to solution. It is still widely seen in older codebases.

import pkg_resources

try:
    dist = pkg_resources.get_distribution("requests")
    print(f"Version: {dist.version}")
except pkg_resources.

*Note: `pkg_resources` is significantly slower at startup because it scans all entry points and metadata on initialization. Avoid it in performance-sensitive CLI tools.*

### The "Quick and Dirty": `package.__version__`

Many packages expose a `__version__` attribute in their top-level `__init__.py`.

```python
import requests
import numpy

print(requests.__version__)
print(numpy.__version__)

Caveats:

  • Not a Standard: PEP 396 suggests this convention, but it is not enforced. Some packages use __version_info__, version, or VERSION.
  • Import Overhead: You must fully import the package. For heavy libraries like torch, tensorflow, or pandas, this adds noticeable latency and memory usage just to read a string.
  • Editable Installs: In development mode (pip install -e .), this attribute might be missing or incorrect if the build metadata hasn't been generated.

Method 3: Inspecting Specific Environments

Modern Python development almost always involves virtual environments (venv, conda, poetry, pipenv). Checking the version globally (system Python) often yields misleading results.

Conda Environments

If you use Anaconda or Miniconda, conda list is the primary tool. It shows packages installed via conda and pip (marked with pypi in the channel column) Simple as that..

conda list numpy
# Or for the exact env:
conda activate my_env
conda list

Poetry / Pipenv / PDM

These modern dependency managers lock versions in a lock file (poetry.lock, Pipfile.Now, lock, pdm. lock).

  • Poetry: poetry show requests or poetry show --tree (shows dependency graph).
  • Pipenv: pipenv run pip show requests or pipenv graph.
  • PDM: pdm list or pdm show requests.

Docker / CI Containers

Inside a Dockerfile or CI pipeline (GitHub Actions, GitLab CI), you typically run the standard pip commands during the build step to verify the install layer:

RUN python -m pip install --no-cache-dir -r requirements.txt \
    && python -m pip list --format=freeze > /tmp/installed_versions.txt

Method 4: Checking Versions Before Installation

Sometimes you need to know the latest available version on PyPI without installing

Querying the latest release without installing the package

When you only need to know which version is currently published on PyPI, pulling the package into your environment just to read its __version__ attribute defeats the purpose. Fortunately, the metadata that PyPI publishes is publicly reachable and can be inspected with a few lightweight calls.

Most guides skip this. Don't Not complicated — just consistent..

Using the standard library (importlib.metadata)

Since Python 3.That's why 8, the importlib. Plus, metadata package (built‑in as of 3. 10) provides a clean API for reading distribution metadata. While it reports the version of an installed distribution, you can combine it with a direct HTTP request to the PyPI JSON endpoint to obtain the newest release Most people skip this — try not to..

import json
import urllib.request

def latest_version_on_pypi(name: str) -> str:
    url = f"https://pypi.org/pypi/{name}/json"
    with urllib.Here's the thing — request. urlopen(url) as resp:
        data = json.

print(latest_version_on_pypi("requests"))   # → 2.31.0 (as of writing)

The json payload contains an info object where the version field holds the most recent release. This approach avoids any import‑time side effects and works even for packages that are not yet installed in the current environment Worth keeping that in mind..

The pip index versions command

Starting with pip 21, the pip index versions sub‑command can enumerate all available releases for a given project and highlight the newest one Surprisingly effective..

pip index versions requests
# Output (truncated):
# requests (2.31.0) (2.30.1) (2.29.23) …
# Latest: 2.31.0

The command prints a space‑separated list of versions; the trailing “Latest:” marker makes it trivial to extract the current maximum. Because it runs entirely in the subprocess, there is no need to import the target package at all.

Quick one‑liner with requests (if you already depend on it)

import requests

def latest_version_on_pypi(name: str) -> str:
    resp = requests.get(f"https://pypi.Now, org/pypi/{name}/json", timeout=10)
    resp. raise_for_status()
    return resp.

print(latest_version_on_pypi("requests"))

Because requests handles redirects, encoding, and error states more gracefully than urllib, this is often the preferred snippet for scripts that already carry the dependency.


Method 5: Detecting Outdated Packages in an Environment

Knowing the installed version is only half the battle; the real operational question is usually “Is there a newer version available?”

pip list --outdated (Built-in)

The simplest way to audit an entire environment is the native flag:

pip list --outdated --format=columns
# Package    Version  Latest  Type
# ---------- -------  ------  ----
# requests   2.28.1   2.31.0  wheel
# urllib3    1.26.15  2.0.3   wheel
  • --format=freeze or --format=json makes the output machine-readable for CI gates.
  • --local restricts checks to packages installed in the current environment (ignoring system/global site-packages if running in a virtualenv).

pip-review (Interactive & Automated Updates)

For a more interactive workflow—especially useful during local development—pip-review wraps the outdated check with update prompts:

pip install pip-review
pip-review --auto      # Upgrade everything automatically
pip-review --interactive # Prompt per package

pur (Parallel Update Reviewer)

If you manage large monorepos or many virtual environments, pur (Python Update Reviewer) parallelizes the PyPI queries, making it significantly faster than sequential pip calls:

pipx install pur   # or pip install pur
pur                # Shows outdated packages with color-coded version diffs
pur -a             # Auto-updates requirements.txt / pyproject.toml pins

Method 6: Programmatic Version Comparison & Constraints

When writing automation (e.g., a custom dependency bot or a pre-commit hook), you rarely want raw strings; you need PEP 440 compliant comparison logic.

The packaging Library (Standard for Tooling)

packaging.version is the reference implementation used by pip, setuptools, and pdm. It correctly handles pre-releases, post-releases, dev releases, and local version identifiers.

from packaging.version import parse as parse_version
from packaging.specifiers import SpecifierSet

installed = parse_version("2.28.1")
latest    = parse_version("2.31.0")

print(installed < latest)  # True

# Check if a version satisfies a requirement specifier
spec = SpecifierSet(">=2.28.0,<3.0.0")
print(spec.contains("2.31.0"))   # True
print(spec.contains("3.0.0"))    # False
print(spec.contains("2.27.0"))   # False

Checking Compatibility Before Upgrading

A common pattern in CI is to verify that the latest version on PyPI still satisfies your project's declared constraints (e.Practically speaking, g. So , in pyproject. Even so, toml or requirements. txt) before allowing a dependabot PR to merge.

import tomllib
from packaging.specifiers import SpecifierSet
from packaging.version import parse as parse_version
import requests

def get_latest_version(pkg_name: str) -> str:
    return requests.get(f"https://pypi.org/pypi/{pkg_name}/json", timeout=10).json()["info"]["version"]

def check_constraints(pyproject_path: str = "pyproject.toml"):
    with open(pyproject_path, "rb") as f:
        data = tomllib.load(f)

    # Handles both [project] dependencies and [tool.In real terms, requirements. On the flip side, dependencies] etc. deps = data.Requirement`
        from packaging.name)
        
        if not req.On the flip side, requirements import Requirement
        req = Requirement(dep)
        latest = get_latest_version(req. poetry.28,<3" -> name="requests", spec=">=2.get("project", {}).28,<3"
        # In production, use `packaging.get("dependencies", [])
    
    for dep in deps:
        # Naive split: "requests>=2.specifier.
Fresh from the Desk

Published Recently

You Might Like

Continue Reading

Thank you for reading about How To Check The Version Of A Python Package. We hope the information has been useful. Feel free to contact us if you have any questions. See you next time — don't forget to bookmark!
⌂ Back to Home