Skip to main content

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 except clauses
  • No use of eval() or exec()
  • 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

FieldRequiredDefaultDescription
nameYesUnique rule identifier
descriptionYesShown in CLI output
typeYesMust be ast
checkYesThe structural check to run (see below)
on_failNowarnwarn or fail
depends_onNoSkip if referenced rule did not pass

Available checks

Check valueWhat it detects
bare_exceptexcept: clauses with no exception type specified
eval_usageAny call to eval() or exec()
missing_docstringFunctions or classes without a docstring
complexityFunctions 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

  1. Comply identifies .py files touched by the diff
  2. Each file is parsed with ast.parse()
  3. The relevant check walks the AST and flags violations
  4. Files with syntax errors are skipped with a warning

Next steps

Rule chaining with depends_on to build conditional rule logic.