A Python code formatter with custom formatting rules
Project description
Pyhone
A Python code formatter with custom formatting rules that complement Ruff. Pyhone focuses on stylistic rules that go beyond what typical formatters handle.
Features
- Multiline Spacing Rule: Automatically ensures multi-line statements (3+ lines by default) have blank lines before and after them for better readability
- Format Mode: Automatically fix formatting issues
- Check Mode: Report violations without modifying files (useful for CI/CD)
- GitHub Actions Integration: Output violations in GitHub Actions annotation format
- Configurable: Customize rules via
pyhone.toml - Fast: Built in Rust for maximum performance
Installation
cargo build --release
The binary will be available at target/release/pyhone.
Usage
Format Files
Apply fixes to Python files:
pyhone file.py
Check Mode
Report violations without fixing:
pyhone --check file.py
Multiple Files
pyhone file1.py file2.py file3.py
Output Formats
Human-readable (default):
pyhone --format human --check file.py
GitHub Actions:
pyhone --format github --check file.py
Custom Configuration
Specify a custom config file:
pyhone --config my-config.toml file.py
Configuration
Create a pyhone.toml file in your project root:
[rules.multiline-spacing]
# Enable/disable the multiline-spacing rule
enabled = true
# Minimum number of lines for a statement to be considered "multi-line"
# Default: 2
min_lines = 2
Rules
Multiline Spacing
Ensures multi-line statements have blank lines before and after them for improved readability.
Example:
Before:
x = 1
def foo():
a = 1
b = 2
c = 3
d = 4
y = 2
After:
x = 1
def foo():
a = 1
b = 2
c = 3
d = 4
y = 2
GitHub Actions Integration
Use Pyhone in your GitHub Actions workflow:
name: Code Quality
on: [push, pull_request]
jobs:
formatting:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: Build Pyhone
run: cargo build --release
- name: Check Python formatting
run: |
find . -name "*.py" -exec ./target/release/pyhone --check --format github {} +
This will automatically annotate your PRs with formatting issues.
Working with Ruff
Pyhone is designed to complement Ruff, not replace it. Use Ruff for:
- Import sorting
- Code linting
- Standard formatting rules
Use Pyhone for:
- Custom spacing rules
- Project-specific style enforcement
Example workflow:
# Run Ruff first
ruff check --fix .
ruff format .
# Then run Pyhone
pyhone **/*.py
Development
Running Tests
cargo test
Project Structure
pyhone/
├── src/
│ ├── main.rs # CLI with clap
│ ├── parser.rs # Python AST parsing
│ ├── config.rs # TOML config loading
│ ├── formatter.rs # Orchestrate rules on source code
│ ├── output.rs # Output formatters (human, github)
│ └── rules/
│ ├── mod.rs # Rule trait + registry
│ └── multiline_spacing.rs
└── pyhone.toml # Example config file
Adding New Rules
- Create a new file in
src/rules/(e.g.,my_rule.rs) - Implement the
FormattingRuletrait:
use crate::rules::{FormattingRule, Violation};
use anyhow::Result;
use rustpython_parser::ast::Mod;
pub struct MyRule;
impl FormattingRule for MyRule {
fn name(&self) -> &str {
"my-rule"
}
fn description(&self) -> &str {
"Description of my rule"
}
fn apply(&self, source: &str, ast: &Mod) -> Result<Vec<Violation>> {
// Your rule logic here
Ok(Vec::new())
}
}
- Register the rule in
src/rules/mod.rs - Add configuration in
src/config.rs - Update the formatter in
src/formatter.rsto use your rule
License
MIT
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
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
Built Distributions
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 pyhone-0.1.5.tar.gz.
File metadata
- Download URL: pyhone-0.1.5.tar.gz
- Upload date:
- Size: 28.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a3b13a4e0e4a8cc8b18a267696193f77e970e38b08a42bb61f22db86290ec05c
|
|
| MD5 |
bfec9c046766079ba79ca90992c9d594
|
|
| BLAKE2b-256 |
f16f366597970e69446e63bf84792595fffec476a17c88f498116f7edec76db6
|
File details
Details for the file pyhone-0.1.5-py3-none-win_amd64.whl.
File metadata
- Download URL: pyhone-0.1.5-py3-none-win_amd64.whl
- Upload date:
- Size: 1.7 MB
- Tags: Python 3, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
484c0a72a2766004af8d766cac4f9b972bcb6f62ba2d9c3dcd49ebc308381a5b
|
|
| MD5 |
d60b294c8edd3b1418c7f22412f907ea
|
|
| BLAKE2b-256 |
acb70d0d79bf0dcca79d82065df5fd2b0993b2fea7cd7b5c5504ada826012e61
|
File details
Details for the file pyhone-0.1.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: pyhone-0.1.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 1.7 MB
- Tags: Python 3, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a9a89f2e1eaf8ebf5ea28069c1c66409e9de84235564b59a530291c1de61df98
|
|
| MD5 |
733212d65cc89780af412f69011c2d08
|
|
| BLAKE2b-256 |
6ede54596bb0bb814c736c79479f87784d85b3484ac4a98dcb0f29bd7c88c572
|
File details
Details for the file pyhone-0.1.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: pyhone-0.1.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 1.6 MB
- Tags: Python 3, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5f78b626838fa920a28ad51961555a4775bd2fd4fef5d57a72243e2e2044c17e
|
|
| MD5 |
08af93417fd2344ae851a24c21835325
|
|
| BLAKE2b-256 |
a3a4a45f5978a7d8bffbc2c28fdf20b1340114280be18b952d83f489b8cf16cd
|
File details
Details for the file pyhone-0.1.5-py3-none-macosx_11_0_arm64.whl.
File metadata
- Download URL: pyhone-0.1.5-py3-none-macosx_11_0_arm64.whl
- Upload date:
- Size: 1.6 MB
- Tags: Python 3, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c08ef5a11463adf9fb45cd26994e07e08c9fd7778db1173df4390a34b842e71a
|
|
| MD5 |
34e8cf5f9fe9d8e8184c2dfe91c3a860
|
|
| BLAKE2b-256 |
092547467c5e9132d4a63956db1acb065c3a5f81a5d30b0785096a92b0850420
|
File details
Details for the file pyhone-0.1.5-py3-none-macosx_10_12_x86_64.whl.
File metadata
- Download URL: pyhone-0.1.5-py3-none-macosx_10_12_x86_64.whl
- Upload date:
- Size: 1.7 MB
- Tags: Python 3, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
697b4ecdd67334adcc7d2c91e878a4a3b39dde94ae841b8e8fa6afe8f3aa7b64
|
|
| MD5 |
e6896e0533dd06725496ea867a7e48d7
|
|
| BLAKE2b-256 |
f4fde267fbf314a381eff00c5eeddb3810efe61bd5039dfb8c1b0e0aa9b6f995
|