DEV Community

Cover image for Why Your Python Docstrings Lie (And How to Fix It)
AmosQuety
AmosQuety

Posted on

Why Your Python Docstrings Lie (And How to Fix It)

Documentation drift is silent. Your code ships, your docstrings stay behind,
and six months later a new developer reads this:

def calculate_discount(price: float, rate: float = 0.1) -> float:
    """Calculate discount.

    Args:
        price (float): Price of the object.
        rate (float): Rate of the object.

    Returns:
        float: Description of the return value.
    """
    return price * (1 - rate)
Enter fullscreen mode Exit fullscreen mode

Technically documented. Completely useless.


The real problem with AI-generated docstrings

AI tools are great at filling the blank — they will generate something for
every function. But "something" is not the same as "accurate." The moment you
rename a parameter, change a return type, or add a new exception, the docstring
is already wrong. There is no enforcement. There is no drift detection.

You end up with documentation that passes a quick glance but fails the developer
who actually needs it.


What deterministic validation gives you

PyCodeCommenter takes a different
approach — rule-based, AST-driven, no external API calls. It does three things:

Generate — produces a starter docstring from the actual function signature:

pycodecommenter generate main.py -i
Enter fullscreen mode Exit fullscreen mode

Validate — checks six things against the real code:

  • Parameters in the docstring match parameters in the signature
  • Type hints match documented types
  • Raised exceptions are documented
  • Return values are documented
  • Format follows Google-style guidelines
  • No placeholders or TODOs left behind
pycodecommenter validate main.py
Enter fullscreen mode Exit fullscreen mode

Coverage — gives you a project-wide documentation score:

pycodecommenter coverage ./src
Enter fullscreen mode Exit fullscreen mode

Where it fits in a real workflow

The most useful place is a pre-commit hook or CI step — not as a blocker on
day one, but as a signal:

# .pre-commit-config.yaml
repos:
  - repo: local
    hooks:
      - id: validate-docstrings
        name: Validate Docstrings
        entry: pycodecommenter validate .
        language: system
        types: [python]
Enter fullscreen mode Exit fullscreen mode

Or in GitHub Actions:

- name: Validate documentation
  run: pycodecommenter validate . 
Enter fullscreen mode Exit fullscreen mode

Now documentation drift gets caught at the PR stage, not six months later.


The new --dry-run flag (v2.1.0)

The latest release adds a safety flag that shows you exactly what would change
before touching any file:

pycodecommenter generate main.py --dry-run
Enter fullscreen mode Exit fullscreen mode

Prints a unified diff to stdout. Exit code 1 if changes exist, 0 if clean —
CI-friendly by design.

Combined with --backup:

pycodecommenter generate main.py -i --backup
Enter fullscreen mode Exit fullscreen mode

Saves main.py.bak before any in-place write. No more accidental overwrites.


Configuration

Drop a .pycodecommenter.yaml in your project root:

style: google
validation:
  level: strict
  check_types: true
  check_exceptions: true
coverage:
  threshold: 80
  fail_below: true
exclude:
  - "*/tests/*"
  - "*/migrations/*"
Enter fullscreen mode Exit fullscreen mode

Try it

pip install pycodecommenter
pycodecommenter generate your_file.py --dry-run
Enter fullscreen mode Exit fullscreen mode

The project is open source under MIT.

GitHub: AmosQuety/PyCodeCommenter

Built by Nabasa Amos — a software engineer
focused on developer tooling and open source.

Top comments (0)