Skip to main content

Python code quality tool with LLM-aware rules, plugin system, and enterprise features

Project description

prefact

PyPI version Python 3.10+ License: Apache-2.0 Code style: black

AI Cost Tracking

PyPI Version Python License AI Cost Human Time Model

  • ๐Ÿค– LLM usage: $7.5000 (53 commits)
  • ๐Ÿ‘ค Human dev: ~$1842 (18.4h @ $100/h, 30min dedup)

Generated on 2026-04-26 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

img.png

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? โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
  1. Scan โ€” each rule walks the AST / CST and emits Issue objects
  2. Fix โ€” rules with auto-fix transform the source (via libcst for formatting-safe changes)
  3. 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

Status

Last updated by taskill at 2026-04-25 13:43 UTC

Metric Value
HEAD 0aac827
Coverage โ€”
Failing tests โ€”
Commits in last cycle 50

Primarily documentation and refactoring work: the docs and README were updated, the code-analysis engine and configuration/CLI were refactored and improved, and Markdown output and example modules were added. Minor fixes include suppressing mypy errors with type: ignore and auto-fixing ruff formatting and imports.

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

prefact-0.1.49.tar.gz (110.8 kB view details)

Uploaded Source

Built Distribution

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

prefact-0.1.49-py3-none-any.whl (135.6 kB view details)

Uploaded Python 3

File details

Details for the file prefact-0.1.49.tar.gz.

File metadata

  • Download URL: prefact-0.1.49.tar.gz
  • Upload date:
  • Size: 110.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for prefact-0.1.49.tar.gz
Algorithm Hash digest
SHA256 f0536f5c4b0902d3691b1b8904cf557930cf18bd7a52def70c586a4d0643ac7a
MD5 aa624f92a1001e16c1ca0a8422a6e640
BLAKE2b-256 56400e0b652f0ba98084f6d3c3ca78782b985df715d86b6e087614cd8c334bb4

See more details on using hashes here.

File details

Details for the file prefact-0.1.49-py3-none-any.whl.

File metadata

  • Download URL: prefact-0.1.49-py3-none-any.whl
  • Upload date:
  • Size: 135.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for prefact-0.1.49-py3-none-any.whl
Algorithm Hash digest
SHA256 664d70827df831d7c7052ef992a8d1688286102f32526e2fd08a36fa7620945c
MD5 2ffb011af40ee172bc79990e026a92bc
BLAKE2b-256 366fc493072eb61d373423a6c32f7800e2e4d444694a56aa3081175f02129762

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