Metadata-Version: 2.4
Name: reloader.py
Version: 0.19.0
Summary: A simple script reloader
Project-URL: Repository, https://github.com/EcmaXp/reloader.py
Author-email: EcmaXp <ecmaxp@ecmaxp.kr>
License-Expression: MIT
License-File: LICENSE
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Topic :: Software Development :: Debuggers
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Software Development :: Testing
Classifier: Topic :: Utilities
Requires-Python: >=3.12
Requires-Dist: watchdog>=5.0.0
Description-Content-Type: text/markdown

# reloader.py

A simple Python hot-reloading tool that automatically reloads modules and scripts when they change, inspired by jurigged and built on watchdog.

## Features

### Core Features

- **Hot Reloading**: Automatically reloads Python code when files change
- **State Preservation**: Patches existing objects in-place, preserving application state
- **Module Support**: Works with scripts, modules, and packages
- **Selective Reloading**: Only reloads changed code chunks (functions, classes, statements)
- **Smart Detection**: Uses AST parsing to identify and reload individual code components

### Execution Modes

- **Script Mode**: Run and reload Python scripts
- **Module Mode**: Execute modules with `-m` flag
- **Function Mode**: Run specific functions from modules
- **Code Mode**: Execute code snippets with `-c` flag
- **Interactive Mode**: Drop into interactive console after execution with `-i`
- **Loop Mode**: Continuously re-execute code on changes with `-l`
- **Daemon Mode**: Run reloader in background thread

### Advanced Features

- **Watch Additional Paths**: Monitor extra files/directories with `-w`
- **Clear Screen**: Clear terminal before each reload with `-C`
- **Debouncing**: Configurable delay to batch rapid file changes
- **Interrupt Handling**: Gracefully interrupt long-running code during reload
- **Path Filtering**: Exclude system paths from reloading
- **Import System Integration**: Hooks into Python's import system via MetaPathFinder
- **Concurrent Monitoring**: Efficiently monitors multiple files using watchdog

### Code Analysis & Patching

- **AST-Based Parsing**: Parses code into reloadable chunks
- **Function Patching**: Updates `__code__`, `__doc__`, `__annotations__`, `__defaults__`
- **Class Patching**: Preserves class instances while updating methods
- **Execution Tracking**: Maintains counters to determine what needs reloading
- **Syntax Error Handling**: Gracefully handles syntax errors without crashing

## Installation

```bash
pip install reloader.py
```

## Usage

### Basic Usage

```bash
# Run a script with auto-reload
python -m reloader script.py

# Run with loop mode (continuously re-executes)
python -m reloader -l script.py

# Run a module
python -m reloader -m module_name

# Run a specific function
python -m reloader -m module_name:function_name

# Execute code snippet
python -m reloader -c "print('Hello, World!')"

# Interactive mode after execution
python -m reloader -i script.py
```

### Advanced Usage

```bash
# Watch additional directories
python -m reloader -l -w /path/to/watch script.py

# Clear screen before each reload
python -m reloader -l -C script.py

# Custom debounce interval (seconds)
python -m reloader -d 0.5 script.py

# Run with arguments
python -m reloader script.py arg1 arg2

# Combine multiple options
python -m reloader -l -C -w ./config -w ./templates app.py
```

## Command Line Options

| Option | Long Form | Description |
|--------|-----------|-------------|
| `-i` | `--interactive` | Enter interactive mode after script execution |
| `-c` | `--code` | Execute code string instead of script |
| `-m` | `--module` | Run module (optionally with :function) |
| `-l` | `--loop` | Enable loop mode for continuous execution |
| `-w` | `--watch` | Watch additional paths (requires --loop) |
| `-C` | `--clear` | Clear screen before each reload |
| `-d` | `--debounce` | Set debounce interval in seconds (default: 0.1) |
| `-P` | `--no-cwd-python-path` | Don't add current directory to Python path |
| | `--disallowed-path-types` | Exclude path types from reloading |
| | `--allowed-path-types` | Include specific path types for reloading |
| | `--version` | Show version information |

## How It Works

1. **File Monitoring**: Uses watchdog to monitor file system events
2. **Code Parsing**: Parses Python files into AST to identify code chunks
3. **Change Detection**: Compares old and new code to find modifications
4. **Hot Patching**: Updates existing objects without replacing them
5. **Execution**: Re-executes changed code while preserving state

## Architecture

### Core Components

- **Watcher**: Monitors file system changes using watchdog
- **CodeModule**: Represents a Python module that can be reloaded
- **CodeChunk**: Individual piece of code (function, class, or statement)
- **ModulePatcher**: Handles the complex logic of patching existing objects
- **Reloader**: Reload engine that applies file changes to watched modules

### Reloader Modes

- `LoopReloader`: Re-executes the target after each change (interrupting long-running scripts)
- `DaemonReloader`: Runs the target once in the foreground while reloading in a daemon thread

### Execution Targets

- `ScriptTarget`: Runs a script file or module as `__main__`
- `FuncTarget`: Runs a specific function from a module
- `CodeTarget`: Evaluates a compiled code snippet (`-c`)
- `ConsoleTarget`: Runs an interactive console (`-i`)

## Limitations

- Cannot reload certain built-in types (e.g., MemberDescriptor)
- Changes to function signatures may require restart
- Some module-level state may not be preserved perfectly
- Threading and async code may have edge cases

## Development

Built with:
- Python 3.12+
- watchdog for file monitoring
- AST for code analysis
- Threading for concurrent operations

## License

MIT License

## Credits

Inspired by [jurigged](https://github.com/breuleux/jurigged) and built on [watchdog](https://github.com/gorakhargosh/watchdog).

Author: EcmaXp