DP005: UnusedDependencyCheck

Overview

Property Value
ID DP005
Name UnusedDependencyCheck
Group dependencies
Severity WARNING

Description

Detects dependencies declared in pyproject.toml that are never imported in the package source code.

Unused dependencies can cause:

  • Increased install time and disk usage for users
  • Larger security attack surface
  • Confusing dependency requirements
  • Maintenance burden keeping unused packages updated

What it checks

The check scans all Python files in your package and compares the imports found against the declared dependencies in pyproject.toml:

# pyproject.toml
[project]
dependencies = [
    "requests>=2.28.0",
    "unused-package>=1.0",  # Never imported - will be flagged
]
# src/mypackage/main.py
import requests  # Used - requests is imported

# unused-package is never imported anywhere

Output:

[dependencies]
 WARN DP005 UnusedDependencyCheck: Unused dependencies: unused-package
      Hint: Remove unused dependencies from pyproject.toml, or add to
      [tool.pycmdcheck.checks.DP005.known-unused] if they are runtime-only
      deps (db drivers, pytest plugins, etc.)

Import-to-package mapping

The check handles cases where import names differ from package names:

Package Name Import Name
pillow PIL
scikit-learn sklearn
beautifulsoup4 bs4
pyyaml yaml
python-dateutil dateutil
opencv-python cv2

How to fix

Remove unused dependencies

If a package is truly unused, remove it from your dependencies:

[project]
dependencies = [
    "requests>=2.28.0",
    # "unused-package>=1.0",  # Removed
]

Mark runtime-only dependencies

Some packages are used at runtime but never directly imported:

  • Database drivers (e.g., psycopg2-binary) - loaded via connection strings
  • Pytest plugins (e.g., pytest-cov) - loaded by pytest automatically
  • ASGI servers (e.g., uvicorn) - run from command line
  • CLI tools (e.g., ruff) - used via subprocess or pre-commit

Add these to the known-unused configuration:

[tool.pycmdcheck.checks.DP005]
known-unused = [
    "psycopg2-binary",  # Database driver loaded via SQLAlchemy
    "pytest-cov",        # Pytest plugin
    "uvicorn",           # ASGI server run from CLI
]

Common runtime-only packages

The check automatically excludes many common runtime-only packages:

  • Pytest plugins: pytest-cov, pytest-xdist, pytest-asyncio
  • Linting tools: ruff, black, mypy, flake8
  • Build tools: build, twine, setuptools, hatchling
  • Database drivers: psycopg2-binary, mysqlclient, pymysql

Configuration

known-unused

List packages that should not be flagged:

[tool.pycmdcheck.checks.DP005]
known-unused = [
    "psycopg2-binary",
    "pytest-cov",
    "uvicorn",
]

exclude-runtime-deps

Control whether common runtime-only packages are automatically excluded (default: true):

[tool.pycmdcheck.checks.DP005]
exclude-runtime-deps = true  # Default

Skip this check

[tool.pycmdcheck]
skip = ["DP005"]

CLI

pycmdcheck --skip DP005

Limitations

The check may not detect:

  • Dynamic imports using importlib.import_module() or __import__()
  • String-based imports in configuration files
  • Conditional imports inside exception handlers (though try/except patterns are scanned)
  • Imports in test files (tests are excluded by default)