CQ008: DocstringCoverage
Overview
| Property | Value |
|---|---|
| ID | CQ008 |
| Name | DocstringCoverage |
| Group | code-quality |
| Severity | WARNING |
Description
Verifies that public functions, classes, and methods have docstrings.
Well-documented code is easier to:
- Understand: Users and contributors can quickly grasp what each function does
- Maintain: Future developers know the intent behind the code
- Use: IDE tooltips and help() show useful information
This check uses AST parsing to identify public definitions and verify they have docstrings.
What it checks
The check scans all Python files in the package (excluding private modules and hidden directories), identifies public functions, classes, and methods, and calculates the docstring coverage percentage:
- PASSED: Coverage is at or above the threshold (default: 80%)
- FAILED: Coverage is below the threshold
- NOT_APPLICABLE: No package found or no public items found
What counts as public?
A definition is considered public if its name does NOT start with an underscore (_):
# Public - counted
def public_function():
"""This counts."""
pass
class PublicClass:
"""This counts."""
def public_method(self):
"""This counts."""
pass
# Private - not counted
def _private_function():
# No docstring needed for private functions
passHow to fix
Add docstrings to public functions
# Before
def calculate_total(items):
return sum(item.price for item in items)
# After
def calculate_total(items):
"""Calculate the total price of all items.
Args:
items: Iterable of items with a price attribute.
Returns:
Sum of all item prices.
"""
return sum(item.price for item in items)Add docstrings to classes
# Before
class OrderProcessor:
def __init__(self, config):
self.config = config
# After
class OrderProcessor:
"""Process customer orders.
Handles validation, payment processing, and order fulfillment.
Attributes:
config: Configuration settings for the processor.
"""
def __init__(self, config):
"""Initialize the processor.
Args:
config: Configuration dictionary with 'api_key' and 'timeout'.
"""
self.config = configUse docstring conventions
Follow a consistent style like Google, NumPy, or Sphinx:
# Google style
def fetch_data(url: str, timeout: int = 30) -> dict:
"""Fetch JSON data from a URL.
Args:
url: The URL to fetch from.
timeout: Request timeout in seconds. Defaults to 30.
Returns:
Parsed JSON response as a dictionary.
Raises:
ConnectionError: If the URL is unreachable.
ValueError: If the response is not valid JSON.
"""
...Make functions private if internal
If a function is truly internal and shouldn’t be documented:
# Rename to make private
def _validate_input(data):
# Internal helper, no docstring required
...Configuration
Adjust coverage threshold
[tool.pycmdcheck.checks.CQ008]
coverage_threshold = 90 # Require 90% coverageInclude private modules
[tool.pycmdcheck.checks.CQ008]
include_private_modules = true # Check _internal.py files tooSkip this check
[tool.pycmdcheck]
skip = ["CQ008"]CLI
pycmdcheck --skip CQ008