AST Rules
AST rules analyze Python source files in the diff using Python's built-in ast module. They check structural properties without running the code.
When to use AST rules
Use ast when you need structural guarantees about Python code:
- No bare
exceptclauses - No use of
eval()orexec() - Functions must have docstrings
- No deeply nested code (complexity limits)
Full example
rules:
- name: no-bare-except
description: Bare except clauses hide errors
type: ast
check: bare_except
on_fail: warn
Field reference
| Field | Required | Default | Description |
|---|---|---|---|
name | Yes | — | Unique rule identifier |
description | Yes | — | Shown in CLI output |
type | Yes | — | Must be ast |
check | Yes | — | The structural check to run (see below) |
on_fail | No | warn | warn or fail |
depends_on | No | — | Skip if referenced rule did not pass |
Available checks
| Check value | What it detects |
|---|---|
bare_except | except: clauses with no exception type specified |
eval_usage | Any call to eval() or exec() |
missing_docstring | Functions or classes without a docstring |
complexity | Functions exceeding a cyclomatic complexity threshold |
bare_except
Flags except: without an exception type. These swallow all exceptions including KeyboardInterrupt and SystemExit.
# Flagged
try:
risky()
except:
pass
# OK
try:
risky()
except ValueError:
pass
eval_usage
Flags any call to eval() or exec(), which execute arbitrary code and are a common security risk.
# Flagged
result = eval(user_input)
exec(dynamic_code)
missing_docstring
Flags functions and classes that lack a docstring. Only applies to new or modified definitions in the diff.
# Flagged
def process_payment(amount):
return charge(amount)
# OK
def process_payment(amount):
"""Charge the customer for the given amount."""
return charge(amount)
complexity
Flags functions with cyclomatic complexity above a threshold. Complexity is computed by counting branches (if, for, while, except, with, assert, Boolean operators).
Default threshold: 10. This is not currently configurable per-rule.
How AST rules work
- Comply identifies
.pyfiles touched by the diff - Each file is parsed with
ast.parse() - The relevant check walks the AST and flags violations
- Files with syntax errors are skipped with a warning
Next steps
Rule chaining with depends_on to build conditional rule logic.