DP008: MinimalDependencies

Overview

Property Value
ID DP008
Name MinimalDependencies
Group dependencies
Severity NOTE

Description

Checks that the package doesn’t have too many direct dependencies.

Having many dependencies can cause:

  • Increased installation time and disk usage
  • Higher risk of dependency conflicts
  • Greater security exposure
  • More maintenance burden when dependencies update

What it checks

The check counts dependencies in pyproject.toml:

# BAD - too many dependencies (>15 by default)
[project]
dependencies = [
    "requests>=2.28.0",
    "numpy>=1.24.0",
    "pandas>=2.0.0",
    "scipy>=1.10.0",
    "matplotlib>=3.7.0",
    "seaborn>=0.12.0",
    "scikit-learn>=1.2.0",
    "tensorflow>=2.12.0",
    "torch>=2.0.0",
    "transformers>=4.28.0",
    "fastapi>=0.95.0",
    "uvicorn>=0.21.0",
    "sqlalchemy>=2.0.0",
    "alembic>=1.10.0",
    "celery>=5.2.0",
    "redis>=4.5.0",
    # ... more dependencies
]

# GOOD - minimal core dependencies
[project]
dependencies = [
    "requests>=2.28.0",
    "click>=8.0.0",
    "pydantic>=2.0.0",
]

[project.optional-dependencies]
ml = ["numpy>=1.24.0", "pandas>=2.0.0", "scikit-learn>=1.2.0"]
api = ["fastapi>=0.95.0", "uvicorn>=0.21.0"]

How to fix

Reduce the number of direct dependencies:

Move optional functionality to extras

[project]
dependencies = [
    "requests>=2.28.0",  # Core functionality only
    "click>=8.0.0",
]

[project.optional-dependencies]
# Group optional features
pdf = ["pypdf>=3.0.0", "reportlab>=4.0.0"]
excel = ["openpyxl>=3.1.0", "xlsxwriter>=3.1.0"]
all = ["mypackage[pdf,excel]"]

Evaluate if all dependencies are needed

  • Can you use the standard library instead?
  • Is the dependency used throughout or just in one place?
  • Can the feature be made optional?

Consider lazy loading

# Instead of top-level import
def process_pdf():
    import pypdf  # Import only when needed
    ...

Configuration

Adjust the threshold

[tool.pycmdcheck.checks.DP008]
max_direct_deps = 20  # Default is 15

Skip this check

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

CLI

pycmdcheck --skip DP008