Managing Installed Packages

This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production.

The reference material consulted while preparing these pages is listed in the Python Reference bibliography.

Once packages are installed, five pip commands report on them and one removes them. This page shows each with pip 26.2.2 on CPython 3.14.6 (2026-10-22), in a venv that holds birdtally with its pretty extra and an older rich 14.3.4, so that something is out of date. Scratch-directory paths are shortened to ….

pip list

python -m pip list
Package        Version
-------------- -------
birdtally      0.1.0
markdown-it-py 4.2.0
mdurl          0.1.2
pip            26.2.2
Pygments       2.21.0
rich           14.3.4
Option Effect

-o, --outdated

Only packages with a newer version on the index, with a Latest and Type column.

-u, --uptodate

Only packages that are current. Packages the index does not know (here birdtally, which is not on PyPI) appear in neither list.

--not-required

Only packages that no other installed package depends on: what you installed directly, more or less.

--format columns|freeze|json

Table (default), name==version lines, or JSON for programs.

--exclude <name>

Leave a package out (can be repeated).

-e, --editable / --exclude-editable

Only, or no, editable installs.

-l, --local, --user, --path <dir>

Restrict to the venv, the user site or one directory.

--pre and the index options

Consider pre-releases and other indexes for --outdated.

python -m pip list --outdated
python -m pip list --not-required
python -m pip list --format=json --exclude pip
Package Version Latest Type
------- ------- ------ -----
rich    14.3.4  15.0.0 wheel
Package   Version
--------- -------
birdtally 0.1.0
pip       26.2.2
rich      14.3.4
[{"name": "birdtally", "version": "0.1.0"}, {"name": "markdown-it-py", "version": "4.2.0"}, {"name": "mdurl", "version": "0.1.2"}, {"name": "Pygments", "version": "2.21.0"}, {"name": "rich", "version": "14.3.4"}]

rich counts as "not required" although birdtally[pretty] needs it, because pip does not record which extras were installed. Since 26.2 --outdated and --uptodate respect --uploaded-prior-to, --only-binary, --no-binary and --prefer-binary when they determine the latest version, and --not-required no longer lists the dependencies of packages excluded with --exclude.

pip show

python -m pip show birdtally
Name: birdtally
Version: 0.1.0
Summary: Tally bird-survey sightings from CSV files.
Home-page: https://example.org/birdtally
Author: The birdtally authors
Author-email:
License-Expression: MIT
Location: …/.venv/lib/python3.14/site-packages
Requires:
Required-by:

Home-page shows the first project URL, License-Expression is the PEP 639 field (shown since pip 25.0), and Requires lists only unconditional dependencies, which is why rich (needed only for the pretty extra) is absent. -f/--files adds the files listed in RECORD; since 26.2 pip reads them only when you ask:

python -m pip show --files birdtally
…
Files:
  ../../../bin/birdtally
  birdtally-0.1.0.dist-info/INSTALLER
  birdtally-0.1.0.dist-info/METADATA
  birdtally-0.1.0.dist-info/RECORD
  birdtally-0.1.0.dist-info/REQUESTED
  birdtally-0.1.0.dist-info/WHEEL
  birdtally-0.1.0.dist-info/entry_points.txt
  birdtally-0.1.0.dist-info/licenses/LICENSE
  birdtally/__init__.py
  birdtally/__pycache__/__init__.cpython-314.pyc
  birdtally/__pycache__/cli.cpython-314.pyc
  birdtally/__pycache__/tally.cpython-314.pyc
  birdtally/cli.py
  birdtally/py.typed
  birdtally/tally.py

pip show of a name that is not installed prints WARNING: Package(s) not found: … and exits with 1.

pip freeze

pip freeze prints the installed distributions in requirements-file format:

python -m pip freeze
birdtally==0.1.0
markdown-it-py==4.2.0
mdurl==0.1.2
Pygments==2.21.0
rich==14.3.4
  • pip itself is left out; --all includes it. On Python 3.12 and later only pip is skipped (older Pythons also skipped setuptools, wheel and distribute, which no longer come with new venvs).

  • --exclude <name> leaves out more packages, --exclude-editable leaves out editable installs.

  • -l/--local, --user and --path <dir> restrict where it looks.

  • -r <file> writes the packages in the order of an existing requirements file, keeping its comments, and appends the rest.

  • Editable and direct-URL installs are written from direct_url.json, for example -e …/birdtally or name @ file:///….

A freeze is not a lock file; see Lock Files & Reproducible Installs. If pip cannot write the output file because of permissions, the documentation’s advice is to redirect to a path you own rather than run pip as root.

pip check

pip check verifies that every installed package’s requirements are satisfied by the other installed packages. It exits with 0 when everything is consistent and 1 otherwise:

No broken requirements found.

After pip install "markdown-it-py<2" broke rich:

rich 15.0.0 has requirement markdown-it-py>=2.2.0, but you have markdown-it-py 1.1.0.

A missing dependency is reported as <pkg> <version> requires <dep>, which is not installed., and a package that is installed for the wrong platform as <pkg> <version> is not supported on this platform. It checks only unconditional requirements and markers, not extras. Run it in CI after the install step; the scenario that produces the conflict above is on Installing Packages.

Source: pip check.

pip inspect

pip inspect (22.2, format 1 stable since 23.0) prints a JSON report of the whole environment, meant for tools. The top level has version, pip_version, installed and environment (the marker values). Each installed item has:

Field Content

metadata

The core metadata as JSON (the PEP 566 transformation): name, version, requires_dist, license_expression, …

metadata_location

The .dist-info directory.

direct_url

The content of direct_url.json, present only for direct-URL, local and editable installs.

requested

Whether REQUESTED exists (the package was asked for directly).

installer

The content of INSTALLER.

For birdtally installed in editable mode from its source tree:

python -m pip inspect > inspect.json
{
  "metadata_location": "…/mg/.venv/lib/python3.14/site-packages/birdtally-0.1.0.dist-info",
  "direct_url": {
    "url": "file://…/pip-flavour/birdtally",
    "dir_info": {
      "editable": true
    }
  },
  "installer": "pip",
  "requested": true
}

(The metadata object is omitted here; its keys were author, classifier, description, description_content_type, keywords, license_expression, license_file, metadata_version, name, project_url, provides_extra, requires_dist, requires_python, summary and version.)

pip uninstall

python -m pip uninstall -y birdtally
Found existing installation: birdtally 0.1.0
Uninstalling birdtally-0.1.0:
  Successfully uninstalled birdtally-0.1.0

-y/--yes skips the confirmation, -r <file> uninstalls everything named in a requirements file, and --break-system-packages overrides PEP 668 as for install. Uninstall removes exactly the files listed in RECORD and does not remove dependencies that are no longer needed (pip does not track why a package was installed); Poetry’s poetry remove and poetry sync do.

Without RECORD pip refuses, because it does not know which files belong to the package. Deleting it by hand reproduces the error:

Found existing installation: birdtally 0.1.0
error: uninstall-no-record-file

× Cannot uninstall birdtally 0.1.0
╰─> The package's contents are unknown: no RECORD file was found for birdtally.

hint: You might be able to recover from this via: pip install --ignore-installed --no-deps birdtally==0.1.0

Packages installed long ago by distutils (setup.py install without setuptools) have only an .egg-info file and fail with the related uninstall-distutils-installed-package error; they can only be removed by hand or by the tool that installed them. Both errors are listed on pip: Troubleshooting.

pip and Poetry

pip Poetry

pip list

poetry show (--top-level for direct dependencies only)

pip list --outdated

poetry show --outdated

pip show rich

poetry show rich

pip freeze

poetry export writes requirements from the lock; poetry show --format json lists the locked packages

pip check

poetry check checks pyproject.toml and the lock, not the environment; poetry install keeps the environment consistent

pip uninstall rich

poetry remove rich (also from pyproject.toml and the lock)

—

poetry show --tree (pip has no dependency tree view)