DC011: DocstringCoverageByModule

Overview

Property Value
ID DC011
Name DocstringCoverageByModule
Group documentation
Severity NOTE

Description

Checks docstring coverage on a per-module basis and reports modules that fall below a configurable threshold.

Per-module coverage is valuable because:

  • It identifies specific files that need documentation attention
  • It prevents new undocumented code from being added
  • It helps prioritize documentation efforts
  • It provides granular feedback compared to package-wide metrics

What it checks

The check walks the AST of each Python module and counts documented vs undocumented items:

  • PASSED: All modules meet the coverage threshold (default: 80%)
  • FAILED: One or more modules are below threshold (reports file, percentage, and missing docstrings)
  • NOT_APPLICABLE: Package directory not found or no documentable items exist

What counts as “documentable”

  • Public functions (not starting with _)
  • Public classes (not starting with _)
  • Public async functions (not starting with _)

What is excluded

  • Private functions and classes (names starting with _)
  • Module-level docstrings (checked separately by DC001)
  • Nested classes and functions within private items

How to fix

Add docstrings to public functions

# Bad: missing docstring
def calculate_total(items):
    return sum(item.price for item in items)

# Good: with docstring
def calculate_total(items):
    """Calculate the total price of all items.

    Args:
        items: Iterable of items with a price attribute.

    Returns:
        The sum of all item prices.
    """
    return sum(item.price for item in items)

Add docstrings to public classes

# Bad: missing docstring
class ShoppingCart:
    def __init__(self):
        self.items = []

# Good: with docstring
class ShoppingCart:
    """A shopping cart that holds items for purchase.

    Attributes:
        items: List of items in the cart.
    """

    def __init__(self):
        self.items = []

Make internal functions private

If a function is implementation detail, make it private:

# Before: public but undocumented helper
def format_price(cents):
    return f"${cents / 100:.2f}"

# After: private helper (doesn't need docstring for coverage)
def _format_price(cents):
    return f"${cents / 100:.2f}"

Focus on high-impact modules first

The check reports which modules have low coverage:

FAILED: 3 module(s) below 80% docstring coverage
  src/mypackage/core.py: 45% coverage (threshold: 80%)
    - missing docstring: function process_data
    - missing docstring: class DataProcessor
    - missing docstring: function validate_input

Start with the most important modules for your users.

Why NOTE severity?

This check is a NOTE because:

  • Documentation completeness is a quality goal, not a hard requirement
  • Some internal modules may intentionally have minimal documentation
  • Coverage thresholds are project-specific
  • It encourages improvement without blocking releases

Configuration

Set coverage threshold

[tool.pycmdcheck]
coverage_threshold = 80  # percent (default)

Lower threshold for legacy codebases:

[tool.pycmdcheck]
coverage_threshold = 50

Higher threshold for public APIs:

[tool.pycmdcheck]
coverage_threshold = 95

Skip this check

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

CLI

pycmdcheck --skip DC011

Best practices

  1. Document public APIs first: Focus on user-facing code
  2. Use consistent style: Choose Google, NumPy, or Sphinx style
  3. Include examples: Add usage examples in docstrings
  4. Generate API docs: Use sphinx-autodoc or mkdocstrings
  5. Review in PRs: Check new code has docstrings

Use docstring templates

Configure your editor to insert docstring templates:

def function_name(arg1, arg2):
    """Short description.

    Longer description if needed.

    Args:
        arg1: Description of arg1.
        arg2: Description of arg2.

    Returns:
        Description of return value.

    Raises:
        ValueError: When invalid input is provided.
    """
    pass

Enforce in CI

# .github/workflows/docs.yml
jobs:
  docstring-coverage:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
      - run: pip install pycmdcheck
      - run: pycmdcheck --only DC011