Python code quality tool with LLM-aware rules, plugin system, and enterprise features
Project description
prefact
AI Cost Tracking
- ๐ค LLM usage: $5.2500 (35 commits)
- ๐ค Human dev: ~$1193 (11.9h @ $100/h, 30min dedup)
Generated on 2026-04-09 using openrouter/qwen/qwen3-coder-next
Automatic Python prefactoring toolkit โ detect, fix, and validate common code issues introduced by LLMs and humans alike.
The Problem
When using LLMs for code generation, they often silently change import paths from absolute to deep relative:
# โ LLM introduces this
from ....llm.generator import generate_strategy
from ....loaders.yaml_loader import save_strategy_yaml
# โ
You wanted this
from planfile.llm.generator import generate_strategy
from planfile.loaders.yaml_loader import save_strategy_yaml
prefact automatically detects, fixes, and validates such issues in a three-phase pipeline.
Features
| Rule | ID | Auto-fix | Description |
|---|---|---|---|
| Relative โ Absolute imports | relative-imports |
โ | Converts from ....x import y to from pkg.x import y |
| Unused imports | unused-imports |
โ | Removes imports never referenced in the module |
| Duplicate imports | duplicate-imports |
โ | Removes the same name imported twice |
| Wildcard imports | wildcard-imports |
๐ | Flags from x import * |
| Unsorted imports | sorted-imports |
๐ | Flags import blocks not ordered stdlibโ3rd-partyโlocal |
| String concatenation | string-concat |
๐ | Flags "Hello " + name โ suggests f-strings |
| Missing return types | missing-return-type |
๐ | Flags public functions without return type hints |
โ = auto-fix ยท ๐ = scan-only (report)
Performance Improvements
- Parallel Processing: Scans files in parallel when enabled
- Smart Filtering: Automatically skips large files (>100KB) and empty files
- Optimized Scanning: Excludes test directories and examples by default
- Deduplication: Prevents duplicate tickets and TODO entries
Examples
The examples/ directory contains comprehensive examples for different use cases:
| Example | Description |
|---|---|
| sample-project | Realistic project with all issues demonstrated |
| 01-individual-rules | Each rule explained with before/after code |
| 02-multiple-rules | Combining multiple rules for comprehensive cleanup |
| 03-output-formats | Console vs JSON output examples |
| 04-custom-rules | Writing your own prefactoring rules |
| 05-ci-cd | GitHub Actions, GitLab CI, Azure DevOps configs |
| 06-api-usage | Using prefact programmatically from Python |
Quick Example
# Try the sample project
cd examples/sample-project
prefact scan --path . --config prefact.yaml
prefact fix --path . --config prefact.yaml
See examples/README.md for a detailed guide to all examples.
Installation
pip install -e .
# with dev dependencies (pytest)
pip install -e ".[dev]"
Quick Start
# Generate config file
prefact init
# List all available rules
prefact rules
# Scan only (no changes)
prefact scan --path ./my_project --package mypackage
# Fix + validate (with backups)
prefact fix --path ./my_project --package mypackage
# Dry-run (show what would change)
prefact fix --path ./my_project --package mypackage --dry-run
# Check a single file
prefact check ./my_project/src/mypackage/core/service.py --package mypackage
# JSON output for CI
prefact fix --path . --format json -o report.json
๐ Want to see prefact in action? Check out our comprehensive examples with real-world scenarios!
Pipeline Architecture
โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโโโโ
โ SCAN โ โโโ โ FIX โ โโโ โ VALIDATE โ
โ โ โ โ โ โ
โ Detect โ โ Apply โ โ Syntax OK? โ
โ issues โ โ fixes โ โ Regressionsโ
โ per ruleโ โ + backupโ โ preserved? โ
โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโโโโ
- Scan โ each rule walks the AST / CST and emits
Issueobjects - Fix โ rules with auto-fix transform the source (via
libcstfor formatting-safe changes) - Validate โ post-fix checks: syntax valid, no regressions, import counts preserved
Configuration
Create prefact.yaml (auto-generated via prefact init):
package_name: planfile
include:
- "**/*.py"
exclude:
- "**/venv/**"
- "**/build/**"
- "**/tests/**"
- "**/test*/**"
- "**/examples/**"
tools:
parallel: true
cache: true
performance:
max_workers: 4
rules:
relative-imports:
enabled: true
severity: warning
unused-imports:
enabled: true
severity: info
duplicate-imports:
enabled: true
wildcard-imports:
enabled: true
severity: error
sorted-imports:
enabled: false
string-concat:
enabled: true
missing-return-type:
enabled: false
Autonomous Mode
Prefact includes an autonomous mode that automatically:
- Scans your project for issues
- Generates TODO.md with all found issues
- Creates tickets in planfile.yaml for tracking
- Updates CHANGELOG.md with fixes
# Run full autonomous workflow
prefact -a
# Or skip tests/examples for faster runs
prefact -a --skip-tests --skip-examples
Performance Improvements
Recent updates have significantly improved performance:
- Parallel Processing: Scans files using multiple workers (configurable)
- Smart Filtering: Skips large files (>100KB) and files with minimal content
- Optimized Exclusions: Automatically excludes test directories and examples
- Deduplication: Prevents duplicate tickets and TODO entries across runs
Python API
from pathlib import Path
from prefact.config import Config
from prefact.engine import RefactoringEngine
config = Config(
project_root=Path("./my_project"),
package_name="planfile",
dry_run=False,
backup=True,
)
engine = RefactoringEngine(config)
result = engine.run()
print(f"Found {result.total_issues} issues")
print(f"Fixed {result.total_fixed}")
print(f"All valid: {result.all_valid}")
Writing Custom Rules
Extend BaseRule and use the @register decorator:
from prefact.rules import BaseRule, register
from prefact.models import Issue, Fix, ValidationResult
@register
class MyCustomRule(BaseRule):
rule_id = "my-custom-rule"
description = "Does something useful."
def scan_file(self, path, source):
# Return list[Issue]
...
def fix(self, path, source, issues):
# Return (fixed_source, list[Fix])
...
def validate(self, path, original, fixed):
# Return ValidationResult
...
CI/CD Integration
# GitHub Actions
- name: prefact check
run: |
pip install ./prefact
prefact scan --path . --format json -o prefact-report.json
prefact fix --path . --dry-run
Running Tests
pip install -e ".[dev]"
pytest -v
License
Licensed under Apache-2.0.
Author
Tom Sapletta
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 prefact-0.1.34.tar.gz.
File metadata
- Download URL: prefact-0.1.34.tar.gz
- Upload date:
- Size: 107.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1b4bdc5980ee7a368d9646a2b07e4dbf2b8760fcb39ada2f32780eccbfcecf76
|
|
| MD5 |
d4711e0f25e68ad9664b58d1bdfa6870
|
|
| BLAKE2b-256 |
8b00b0565640768eade953c1c2f3e4614e2999771b15689ccf47d1450a05b7bf
|
File details
Details for the file prefact-0.1.34-py3-none-any.whl.
File metadata
- Download URL: prefact-0.1.34-py3-none-any.whl
- Upload date:
- Size: 134.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b5a08d068f1bfb96c41184452de8801193d150ca1b6575559943c9c3fac591e6
|
|
| MD5 |
77d062e8ef671f4e58ea44b9c4d350fd
|
|
| BLAKE2b-256 |
6b9a895094c1e1eba34e060e5246248cad54a15d9e08aa9ef03275491a93121e
|