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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
187f9b877748f0e35d9d7b345239344d2a3fc2b577c2a3834e5429726cba150a
|
|
| MD5 |
16591b19fdaf15f7e27c41fd750d79d2
|
|
| BLAKE2b-256 |
0ae73743149751e1a2777ffab9cfa943ed1374c456d5cf32af896a39911afa64
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a903283ed22133961b9588e774b5d3a4b916e16c382e7bcb0d154590b6be3731
|
|
| MD5 |
3be1c8346cc1046d50cd88d55bdfdd58
|
|
| BLAKE2b-256 |
ef64e2c18b1da93a91206543c3a9e363c9f4618b311ca8fafc021b5b2fe5cd48
|