Skip to main content

Repair broken Python code before formatting it.

Project description

PyRepair

Repair broken Python code before formatting it.

Tools like Black, Ruff, and autopep8 require valid Python. PyRepair sits upstream — it fixes indentation errors, tab/space mixes, and missing block bodies so those tools can run.

Broken Python → PyRepair → Valid Python → Black/Ruff → Clean Python

Installation

pip install pyrepair

Or install from source:

git clone https://github.com/sandeep-kumar-mehta/pyrepair.git
cd pyrepair
pip install -e ".[dev]"

Quick Start

# Repair a single file in-place
pyrepair broken.py

# Preview changes without writing (safe)
pyrepair broken.py --dry-run

# Repair all .py files in a directory
pyrepair src/

# Create a backup before writing
pyrepair broken.py --backup

# Show detailed issue table
pyrepair broken.py --report

What Gets Fixed

Rule What It Does
tabs_to_spaces Converts leading \t to 4 spaces
mixed_indent Fixes lines that mix tabs and spaces
indentation_repair Indents body of if/for/while/def/class blocks
missing_block Inserts pass when a compound statement has no body

CLI Reference

pyrepair [TARGET] [OPTIONS]

Arguments:
  TARGET    Python file or directory to repair.

Options:
  --dry-run     Show diff only. Do NOT write changes.
  --backup      Save .bak copy before overwriting.
  --report, -r  Print detailed issue table for each file.
  --help        Show this message and exit.

Python API

from pathlib import Path
from pyrepair import RepairEngine

engine = RepairEngine()

# Repair a file (returns RepairResult — does NOT write to disk)
result = engine.repair_file(Path("broken.py"))

print(result.status)           # RepairStatus.SUCCESS
print(result.total_issues)     # 5
print(result.total_fixed)      # 5
print(result.validation_passed)# True
print(result.repaired_source)  # fixed source code string

# Repair a raw string
result = engine.repair_source("if True:\nprint('hi')\n")

Adding Custom Rules

from pyrepair import RepairEngine
from pyrepair.repair_engine import RepairRule
from pyrepair.models import Issue, Severity

class RemoveDebugPrintsRule(RepairRule):
    name = "remove_debug_prints"
    description = "Remove debug print statements."

    def detect(self, source: str) -> list[Issue]:
        issues = []
        for i, line in enumerate(source.splitlines(), 1):
            if 'print("DEBUG' in line:
                issues.append(Issue(
                    rule_name=self.name,
                    description="Debug print found.",
                    line_number=i,
                    severity=Severity.WARNING,
                    original=line,
                ))
        return issues

    def repair(self, source: str) -> str:
        lines = [l for l in source.splitlines() if 'print("DEBUG' not in l]
        return "\n".join(lines)

engine = RepairEngine()
engine.add_rule(RemoveDebugPrintsRule())

Architecture

pyrepair/
├── cli.py            ← Typer CLI (no business logic)
├── scanner.py        ← File discovery
├── repair_engine.py  ← Rule pipeline + RepairEngine
├── models.py         ← Pure data classes (Issue, RepairResult)
├── report.py         ← Rich terminal output
└── utils.py          ← Shared helpers (read/write/validate)

Layers are kept separate (SOLID). The CLI only calls the engine and reporter.


Roadmap

v1.0 Indentation repair, tab conversion, missing block, AST validation

v2.0 Unused/duplicate import detection, import sorting, dead code detection

v3.0 VS Code extension, HTML reports


Contributing

See CONTRIBUTING.md.


License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyrepair-1.0.0.tar.gz (16.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyrepair-1.0.0-py3-none-any.whl (14.8 kB view details)

Uploaded Python 3

File details

Details for the file pyrepair-1.0.0.tar.gz.

File metadata

  • Download URL: pyrepair-1.0.0.tar.gz
  • Upload date:
  • Size: 16.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for pyrepair-1.0.0.tar.gz
Algorithm Hash digest
SHA256 187f9b877748f0e35d9d7b345239344d2a3fc2b577c2a3834e5429726cba150a
MD5 16591b19fdaf15f7e27c41fd750d79d2
BLAKE2b-256 0ae73743149751e1a2777ffab9cfa943ed1374c456d5cf32af896a39911afa64

See more details on using hashes here.

File details

Details for the file pyrepair-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: pyrepair-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 14.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for pyrepair-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a903283ed22133961b9588e774b5d3a4b916e16c382e7bcb0d154590b6be3731
MD5 3be1c8346cc1046d50cd88d55bdfdd58
BLAKE2b-256 ef64e2c18b1da93a91206543c3a9e363c9f4618b311ca8fafc021b5b2fe5cd48

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page