Skip to content
sarobPublic

About

Deterministic codebase intelligence for Python — dead code, duplication, complexity, architecture boundaries, and quality scoring.

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

14 Commits

Folders and files

Repository files navigation

hallow

Deterministic codebase intelligence for Python.

Dead code, duplication, circular dependencies, complexity scoring, architecture boundaries — one tool, zero config, machine-readable output.

Inspired by fallow (JS/TS), adapted for Python's import system, packaging, and dynamic features.

Status

Phase Scope Status
Phase 1 Foundation + Dead Code Complete
Phase 2 Complexity + Health + Duplication Complete
Phase 3 Boundaries + Plugins + Fix Complete
Phase 4 Output Formats + Audit + CI Complete
Phase 5 Security + MCP + Polish Complete

Install

pip install hallow

Or from source:

git clone https://github.com/sarob/hallow.git
cd hallow
pip install -e ".[dev]"

Usage

# Full scan — dead code + duplication + health
$ hallow

# Dead code only
$ hallow check --format sarif --output findings.sarif

# Health score
$ hallow health --score
  Health: 82/100 (B)
  Complexity hotspots: 3
  Maintainability: 71.4 avg

# Duplicate detection
$ hallow dupes --mode mild --min-lines 8

# PR audit — only flag new issues in changed files
$ hallow audit --changed-since origin/main --ci

# Auto-fix
$ hallow fix --dry-run
  Would remove: 4 unused imports, 2 dead files, 1 unused dep

# Architecture boundary check
$ hallow check --boundaries --preset layered

# Security scan
$ hallow security

# MCP server
$ hallow mcp --stdio

Programmatic API

from hallow.api import detect_dead_code, detect_circular_dependencies, compute_complexity

# Dead code analysis
results = detect_dead_code(root="./my-project")
for finding in results.findings:
    print(f"{finding.location.file}:{finding.location.line} {finding.message}")

# Circular imports
cycles = detect_circular_dependencies(root="./my-project")
for cycle in cycles:
    print(" -> ".join(cycle["modules"]))

# Complexity metrics
for func in compute_complexity(root="./my-project"):
    if func["cyclomatic"] > 10:
        print(f"{func['file']}:{func['name']} cc={func['cyclomatic']}")

Why Hallow

No single tool covers Python the way Fallow covers JS/TS. Today you need vulture for dead code, radon for complexity, import-linter for circular deps, pylint for duplication — each with its own config, output format, and no awareness of the others. None detect unused files, unused dependencies, or offer project-level quality scoring.

Hallow runs all analyses through one pipeline, one config, one data model:

Discover → Extract → Resolve → Graph → Analyze → Report

It uses Python's built-in ast module — no external parser — and produces unified output in JSON, SARIF, Markdown, or Rich ANSI.

Architecture

Nine modules mirroring Fallow's crate structure:

Module Role
hallow.types Pydantic models: ModuleInfo, Finding, AnalysisResults, Severity. Pure schema, no logic.
hallow.config Config from .hallowrc.toml or pyproject.toml [tool.hallow]. Zero-config defaults.
hallow.extract AST extraction via ast.parse(). Produces ModuleInfo per file: imports, exports, __all__, complexity.
hallow.graph Module graph from ModuleInfo. Import resolution, reachability, cycle detection (Tarjan's SCC).
hallow.core Analysis orchestration. Detectors run in parallel: dead code, unused deps, circular imports, duplication, boundaries.
hallow.plugins Framework awareness. Auto-activated from pyproject.toml deps: Django, Flask, FastAPI, pytest, Celery.
hallow.output Formatters: JSON, SARIF, Markdown, CodeClimate, GitHub annotations, compact, human (Rich ANSI).
hallow.cli Typer CLI: hallow check, health, dupes, audit, fix, security, watch.
hallow.mcp MCP server. 12+ tools for agent-driven codebase intelligence.

Features

Dead code detection

  • Unused files (unreachable from entry points)
  • Unused imports, functions, classes, variables
  • Unused dependencies (declared in pyproject.toml but never imported)
  • Unlisted dependencies (imported but not declared)
  • Unused __all__ entries

Complexity & health

  • Per-function cyclomatic + cognitive complexity
  • Project-level health score (0-100, A-F grade)
  • Maintainability index
  • Complexity hotspot identification

Duplication

  • Clone detection via tokenization + suffix array + LCP
  • Four modes: strict (exact), mild (normalized identifiers), weak (structure only), semantic

Circular dependencies

  • Detection via Tarjan's strongly connected components
  • Full cycle chain visualization

Architecture boundaries

  • Layered, hexagonal, feature-sliced presets
  • Custom zone definitions with import rules
  • Namespace package awareness

Framework plugins

  • Auto-detected from pyproject.toml dependencies
  • Django, Flask, FastAPI, pytest, Celery
  • Suppresses false positives for framework-registered exports (decorators, entry files, migrations)

Auto-fix

  • hallow fix --dry-run previews safe changes
  • hallow fix --apply removes unused imports, deletes dead files, strips unused deps from pyproject.toml

Security

  • Hardcoded secrets (API keys, tokens, passwords, private keys, JWTs)
  • Taint sink detection (eval, exec, os.system, subprocess, pickle, SQL injection)
  • Safe-context filtering (env vars, config lookups, placeholders)

Output formats

  • Human (Rich ANSI), JSON, compact
  • SARIF v2.1.0 (GitHub code scanning, VS Code)
  • Markdown (PR comments and reports)
  • CodeClimate JSON (GitLab Code Quality)
  • GitHub Actions annotations (::error/::warning)

CI integration

  • GitHub Action workflow definition
  • Pre-commit hook configuration
  • --ci exit code gating
  • PR-scoped audit with hallow audit --changed-since
  • Baseline files (--save-baseline / --baseline) for regression prevention

MCP server

  • JSON-RPC 2.0 over stdio — hallow mcp --stdio
  • 6 tools: analyze, health, complexity, cycles, duplicates, explain
  • Agent-driven codebase intelligence via Model Context Protocol

Configuration

Zero config by default. Customize via .hallowrc.toml or pyproject.toml:

# .hallowrc.toml
entry = ["src/main.py"]
ignore_patterns = ["**/migrations/**"]

[rules]
unused-files = "error"      # error (default), warn, off
unused-imports = "error"
unused-variables = "warn"
circular-dependencies = "error"
high-complexity = "warn"

[duplicates]
mode = "mild"               # strict, mild, weak, semantic
min_tokens = 50
min_lines = 5

[health]
max_cyclomatic = 20
max_cognitive = 15

Or in pyproject.toml:

[tool.hallow]
entry = ["src/main.py"]

[tool.hallow.rules]
unused-files = "error"
unused-imports = "warn"

Python-Specific Design

Hallow is not a port of Fallow — it's built for Python's idioms:

  • ast.parse() over OXC — Python's built-in AST is fast, complete, and zero-dependency. Handles all 3.11+ syntax.
  • Import resolution — relative imports, namespace packages, conditional imports (try/except), lazy imports, sys.path manipulation.
  • No explicit exports — Python uses __all__ (optional) and convention (leading underscore). Hallow treats all public module-level names as exports unless __all__ narrows the surface.
  • Dynamic features — getattr(), **kwargs, metaclasses, decorator registries. Framework plugins handle common patterns; suppression comments handle the rest.
  • pyproject.toml over package.json — dependency parsing from [project.dependencies], [project.optional-dependencies], requirements.txt fallback.
  • Parallelism via ProcessPoolExecutor — Python's GIL makes threading insufficient for CPU-bound AST parsing. Content-hash caching keeps re-analysis fast.

Stack

  • Python 3.11+ — tomllib, StrEnum, ExceptionGroup
  • Typer — typed CLI with Rich integration
  • Pydantic v2 — config validation, result schemas, JSON serialization
  • Rich — ANSI terminal output
  • Hatch — build backend
  • pytest — test suite

Development

git clone https://github.com/sarob/hallow.git
cd hallow
uv venv && uv pip install -e ".[dev]"

uv run pytest              # run tests
uv run ruff check .        # lint
uv run ruff format .       # format
uv run hallow check --root .  # self-analysis

License

Apache License 2.0 — see LICENSE for details.

About

Deterministic codebase intelligence for Python — dead code, duplication, complexity, architecture boundaries, and quality scoring.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages