Skip to main content

No project description provided

Project description

pyxplod

Python Version License: MIT

pyxplod is a Python refactoring tool that "explodes" Python files by extracting each class and function definition into separate files, automatically replacing them with imports. This helps break down large Python modules into smaller, more manageable pieces while maintaining functionality.

Features

  • 🔍 Intelligent code extraction: Uses Python's AST to accurately identify and extract classes and functions
  • 📁 Structure preservation: Maintains your project's directory structure in the output
  • 🔗 Automatic imports: Replaces extracted code with proper relative imports
  • Smart import optimization: Only includes imports actually used in each extracted file (v0.3.0+)
  • 🛡️ Safe operation: Non-destructive - creates new files without modifying originals
  • 📊 Progress tracking: Visual progress bars and detailed logging with rich and loguru
  • 🎯 Smart naming: Converts class/function names to snake_case for consistent file naming
  • 🗂️ Dual methods: Choose between flat file structure or package-based organization
  • Fast processing: Efficiently handles large codebases with error recovery

Installation

From PyPI (when published)

pip install pyxplod

Or using uv:

uv pip install pyxplod

From Source (Current)

# Clone the repository
git clone https://github.com/twardoch/pyxplod.git
cd pyxplod

# Install in development mode
uv pip install -e .

Usage

Basic Usage (Files Method)

pyxplod --input /path/to/source --output /path/to/output

Using Dirs Method

pyxplod --input /path/to/source --output /path/to/output --method dirs

With Verbose Logging

pyxplod --input /path/to/source --output /path/to/output --verbose

Methods

pyxplod supports two different explosion methods:

Files Method (Default)

The files method creates separate files in the same directory structure, with each extracted class/function having a filename prefix based on the original file.

Dirs Method

The dirs method creates a directory (package) for each Python file, with extracted classes and functions as separate modules within that package. An __init__.py file contains imports and any remaining module-level code.

How It Works

Given a Python file like this:

# src/utils.py
import os
from typing import List

class FileHandler:
    def __init__(self):
        self.files = []
    
    def add_file(self, path: str):
        self.files.append(path)

def process_data(data: List[str]) -> str:
    return "\n".join(data)

CONSTANT = "some_value"

pyxplod will create different structures based on the method used:

Files Method Output (Default)

output/
└── src/
    ├── utils.py                    # Modified main file
    ├── utils_file_handler.py       # Extracted class
    └── utils_process_data.py       # Extracted function

Dirs Method Output

output/
└── src/
    └── utils/
        ├── __init__.py             # Module interface with imports
        ├── file_handler.py         # Extracted class
        └── process_data.py         # Extracted function

Example Contents

Files Method Output

output/src/utils.py:

from typing import List
from .utils_file_handler import FileHandler
from .utils_process_data import process_data

CONSTANT = "some_value"

output/src/utils_file_handler.py:

class FileHandler:
    def __init__(self):
        self.files = []
    
    def add_file(self, path: str):
        self.files.append(path)

output/src/utils_process_data.py:

from typing import List

def process_data(data: List[str]) -> str:
    return "\n".join(data)

Dirs Method Output

output/src/utils/init.py:

from typing import List
from .file_handler import FileHandler
from .process_data import process_data

CONSTANT = "some_value"

output/src/utils/file_handler.py:

class FileHandler:
    def __init__(self):
        self.files = []
    
    def add_file(self, path: str):
        self.files.append(path)

output/src/utils/process_data.py:

from typing import List

def process_data(data: List[str]) -> str:
    return "\n".join(data)

Note: pyxplod v0.3.0+ automatically optimizes imports - only the imports actually used in each file are included, reducing file sizes by 30-50%.

Advanced Options

Command Line Arguments

pyxplod --help
Argument Description Default Example
--input Source directory to process Required --input ./src
--output Output directory for exploded files Required --output ./output
--method Processing method: files or dirs files --method dirs
--verbose Enable detailed logging False --verbose

Processing Methods Comparison

Aspect Files Method Dirs Method
Structure Flat files with prefixes Package directories
File naming utils_my_class.py my_class.py
Organization Same directory Subdirectories with __init__.py
Best for Simple modules, quick extraction Complex modules, clean organization
Import style from .utils_my_class import MyClass from .utils.my_class import MyClass

Use Cases

  • Refactoring large modules: Break down monolithic Python files (500+ lines) into smaller, focused modules
  • Code organization: Improve project structure by separating concerns and creating logical boundaries
  • Testing: Make it easier to test individual components in isolation with focused test files
  • Code review: Simplify code reviews by creating smaller, single-purpose files that are easier to understand
  • Legacy code: Gradually modernize legacy codebases by extracting reusable components
  • Microservices preparation: Extract functionality before splitting monoliths into microservices
  • Educational purposes: Help understand code structure by separating concerns visually

Features in Detail

Smart Import Handling

  • Preserves all module-level imports in extracted files
  • Generates relative imports for the extracted components
  • Maintains import order and structure

Error Handling

  • Gracefully handles syntax errors in source files
  • Skips files that cannot be parsed
  • Provides detailed error messages for troubleshooting

File Naming

  • Converts CamelCase to snake_case automatically
  • Handles naming conflicts with automatic deduplication
  • Preserves meaningful names while ensuring filesystem compatibility

Development

Setup Development Environment

# Clone the repository
git clone https://github.com/twardoch/pyxplod.git
cd pyxplod

# Install in development mode
pip install -e .

# Install development dependencies
pip install -e ".[dev,test]"

Running Tests

# Run all tests
pytest

# Run with coverage
pytest --cov=pyxplod

# Run specific test
pytest tests/test_pyxplod.py::TestProcessing::test_process_simple_file

Code Quality

# Auto-format, lint and test (recommended)
fd -e py -x autoflake {}; fd -e py -x pyupgrade --py311-plus {}; fd -e py -x ruff check --output-format=github --fix --unsafe-fixes {}; fd -e py -x ruff format --respect-gitignore --target-version py311 {}; python -m pytest;

# Individual commands
ruff check src/ tests/       # Linting
ruff format src/ tests/      # Formatting  
mypy src/                    # Type checking

Requirements

  • Python 3.10 or higher
  • Dependencies:
    • fire - CLI interface
    • loguru - Enhanced logging
    • rich - Progress bars and formatting
    • Standard library: ast, pathlib, os

License

MIT License - see LICENSE file for details.

Limitations & Known Issues

  • Comments: Comments between class/function definitions may be lost during processing
  • Formatting: Code formatting may change due to AST parsing and regeneration
  • Nested definitions: Only top-level classes and functions are extracted (nested classes/functions remain in original files)
  • Decorators: Some complex decorator chains may need manual review after extraction
  • Large files: Very large files (>1000 lines) may require more memory and processing time

See TODO.md for a complete list of planned improvements.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

Development Setup

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Set up development environment:
    uv pip install -e ".[dev,test]"
    
  4. Make your changes and add tests
  5. Run the test suite:
    python -m pytest --cov=pyxplod
    
  6. Ensure code quality:
    fd -e py -x ruff check --fix {}; fd -e py -x ruff format {}
    
  7. Commit your changes (git commit -m 'Add some amazing feature')
  8. Push to the branch (git push origin feature/amazing-feature)
  9. Open a Pull Request

Code Guidelines

  • Follow PEP 8 style guidelines
  • Add type hints using simple syntax (list, dict, str | None)
  • Write clear docstrings for all functions and classes
  • Add tests for new features and bug fixes
  • Keep functions focused and single-purpose

Changelog

See CHANGELOG.md for a detailed history of changes.

Author

Created by Adam Twardoch

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

pyxplod-1.0.0.tar.gz (9.4 kB view details)

Uploaded Source

Built Distribution

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

pyxplod-1.0.0-py3-none-any.whl (6.6 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: pyxplod-1.0.0.tar.gz
  • Upload date:
  • Size: 9.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.6.14

File hashes

Hashes for pyxplod-1.0.0.tar.gz
Algorithm Hash digest
SHA256 3a842f6d811421905a450171e6cb5c8202ac4203919a15b3a75d173ada9d0742
MD5 cfcafc940e8809c235ff32f45802943b
BLAKE2b-256 ba0c8f4da13fcf35642c8aa5ff749225275a63f4f75e4b7086ba2dc608a1a8ca

See more details on using hashes here.

File details

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

File metadata

  • Download URL: pyxplod-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 6.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.6.14

File hashes

Hashes for pyxplod-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e93d1d7e03b85a2facefac9a4f455e26aa2d046ea9c310d86c86fe210594bd31
MD5 ff71a5bbe459f8faf6688e2676b03bae
BLAKE2b-256 b8307bbe47320fb4558d294356ec1fc633e419465541f6d55cf221c15fc4655a

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