Skip to content

Repository files navigation

crap4py

CI PyPI

Python port of Uncle Bob's crap4go and crap4clj — CRAP score per function for Python source files.

CRAP (Change Risk Anti-Pattern) = CC² × (1 − coverage)³ + CC — a per-function metric combining cyclomatic complexity and branch coverage. Higher means riskier to change. Conventional threshold: 30.

Install

# Run without installing
uvx crap4py

# Persistent install
uv tool install crap4py

Usage

crap4py src/ --lcov lcov.info

Generate lcov.info with coverage.py:

pytest --cov --cov-branch --cov-report=lcov:lcov.info

Output

CRAP Report
Function                    | Module                        | CC | Cov%  | CRAP
----------------------------+-------------------------------+----+-------+-----
_sort_key                   | src/crap4py/_crap.py          |  3 |  33.3 |  9.9
main                        | src/crap4py/__main__.py       |  2 | 100.0 |  2.0

Options

Flag Description
--lcov PATH LCOV branch-coverage file (required)
--max-crap N Exit non-zero if any function exceeds N (CI gate)
--max-workers N Parallel workers for large codebases
--fragment TEXT Only analyse files whose path contains TEXT

CI gate

crap4py src/ --lcov lcov.info --max-crap 30

Exits non-zero if any function's CRAP score exceeds the threshold. N/A functions (no coverage data) never trip the gate.

How it works

  • Complexity — cyclomatic complexity from Python's ast per def/async def
  • Coverage — branch coverage from LCOV BRDA records intersected with each function's line range
  • Skips.gitignore-ignored paths and test files (test_*.py, *_test.py) are excluded automatically

See also: crap4go, crap4clj.

About

Python CRAP score analyzer: cyclomatic complexity + branch coverage per function

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages