CQ011: FunctionLength
Overview
| Property | Value |
|---|---|
| ID | CQ011 |
| Name | FunctionLength |
| Group | code-quality |
| Severity | NOTE |
Description
Warns when functions exceed a configurable line threshold (default: 50 lines).
Long functions indicate:
- Multiple responsibilities: Functions doing too many things
- Poor abstraction: Missing helper functions or classes
- Difficult testing: Hard to test individual behaviors
- Code smells: Often accompanied by deep nesting and complexity
This check uses AST parsing to measure function length from definition to end.
What it checks
The check scans all Python files in the package (excluding hidden directories and __pycache__), measures the line count of each function and method, and reports those exceeding the threshold:
- PASSED: All functions are within the line limit
- FAILED: One or more functions exceed the limit
- NOT_APPLICABLE: Package directory not found
How length is calculated
Function length is measured from the def line to the last line of the function body, inclusive of:
- Docstrings
- Comments
- Blank lines within the function
- All nested blocks and statements
def example(): # Line 1
"""Docstring. # Line 2
More docs. # Line 4
""" # Line 5
x = 1 # Line 6
return x # Line 7
# Total: 7 linesHow to fix
Extract helper functions
# Before - 60 lines
def process_order(order):
# Validate order (20 lines)
if not order.customer:
raise ValueError("No customer")
if not order.items:
raise ValueError("No items")
# ... more validation
# Calculate totals (20 lines)
subtotal = sum(item.price for item in order.items)
tax = subtotal * 0.08
# ... more calculations
# Send notifications (20 lines)
send_email(order.customer.email, ...)
# ... more notifications
# After - each function focused
def process_order(order):
validate_order(order)
totals = calculate_totals(order)
send_order_notifications(order, totals)
return totals
def validate_order(order):
"""Validate order has required fields."""
if not order.customer:
raise ValueError("No customer")
if not order.items:
raise ValueError("No items")
def calculate_totals(order):
"""Calculate order subtotal, tax, and total."""
subtotal = sum(item.price for item in order.items)
tax = subtotal * TAX_RATE
return OrderTotals(subtotal=subtotal, tax=tax)
def send_order_notifications(order, totals):
"""Send order confirmation emails."""
send_email(order.customer.email, ...)Use early returns to reduce nesting
# Before
def process(data):
if data:
if data.valid:
if data.ready:
# 40 lines of processing
...
# After
def process(data):
if not data:
return None
if not data.valid:
raise ValueError("Invalid data")
if not data.ready:
return pending_result()
return _process_ready_data(data)Extract complex conditionals
# Before
def should_process(item):
if (item.status == "active" and
item.created_at > threshold and
item.owner in allowed_users and
not item.is_deleted and
item.type in ALLOWED_TYPES):
# processing logic...
# After
def should_process(item):
if not is_eligible(item):
return False
return _do_processing(item)
def is_eligible(item):
return (
item.status == "active" and
item.created_at > threshold and
item.owner in allowed_users and
not item.is_deleted and
item.type in ALLOWED_TYPES
)Configuration
Adjust line threshold
[tool.pycmdcheck.checks.CQ011]
max_function_lines = 30 # Stricter limit[tool.pycmdcheck.checks.CQ011]
max_function_lines = 100 # More lenientSkip this check
[tool.pycmdcheck]
skip = ["CQ011"]CLI
pycmdcheck --skip CQ011