Skip to main content

A Python code formatter with custom formatting rules

Project description

Pyhone

CI

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

  1. Create a new file in src/rules/ (e.g., my_rule.rs)
  2. Implement the FormattingRule trait:
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())
    }
}
  1. Register the rule in src/rules/mod.rs
  2. Add configuration in src/config.rs
  3. Update the formatter in src/formatter.rs to 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

pyhone-0.1.0.tar.gz (25.6 kB view details)

Uploaded Source

Built Distributions

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

pyhone-0.1.0-py3-none-win_amd64.whl (1.7 MB view details)

Uploaded Python 3Windows x86-64

pyhone-0.1.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.7 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

pyhone-0.1.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.6 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

pyhone-0.1.0-py3-none-macosx_11_0_arm64.whl (1.6 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

pyhone-0.1.0-py3-none-macosx_10_12_x86_64.whl (1.6 MB view details)

Uploaded Python 3macOS 10.12+ x86-64

File details

Details for the file pyhone-0.1.0.tar.gz.

File metadata

  • Download URL: pyhone-0.1.0.tar.gz
  • Upload date:
  • Size: 25.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: maturin/1.12.6

File hashes

Hashes for pyhone-0.1.0.tar.gz
Algorithm Hash digest
SHA256 9981e74cbba8aecb2405f6b6ddcc2b90311310439a49760cecdb29060a836870
MD5 4eee1be6fc107e39dbb99a1424d6e1f5
BLAKE2b-256 9b5a80bcdac7d69c349a216a20180181607bc1bac665ad2451b56480cda37400

See more details on using hashes here.

File details

Details for the file pyhone-0.1.0-py3-none-win_amd64.whl.

File metadata

  • Download URL: pyhone-0.1.0-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.12.6

File hashes

Hashes for pyhone-0.1.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 8c6c898a88c85017833a09a592de2d46e02319a359b84bc9d55cb3d8208542de
MD5 32cb89f6202144beb622706b1f0b386e
BLAKE2b-256 885e12c80077498b1c16314f5283be94e3a45a42f54d4cb4e474c96585e27b05

See more details on using hashes here.

File details

Details for the file pyhone-0.1.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pyhone-0.1.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 276cc4ee68949facfdf776c60d14f909a714f91591547478a812147bfe44f340
MD5 496d19f6150ea36e87f4323bc498f046
BLAKE2b-256 23a8ee1ec38396a1f382714190be70820861f74cb6ac45877cb09eb395af5fbd

See more details on using hashes here.

File details

Details for the file pyhone-0.1.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for pyhone-0.1.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 35806c206a05d090838de7b847287d769d88b3c11f9eb66d5e03b9b39fc982ab
MD5 b96b048c62d03917ec2283f2677d94c7
BLAKE2b-256 1a64f1ddaadc664c824cca88a4046c2e4374b303d74679a13bb7dd7f380aad90

See more details on using hashes here.

File details

Details for the file pyhone-0.1.0-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pyhone-0.1.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 3f4bcfb091517e2236453795122047f775565c07a8dd4e681a94960c01e58e0e
MD5 f612142d578588c2966f85604a47ae1d
BLAKE2b-256 766489ace88f905f165e8a6aad76c710d7b991fd7948f5b4e3547d0e986af30d

See more details on using hashes here.

File details

Details for the file pyhone-0.1.0-py3-none-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for pyhone-0.1.0-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 f1674ab57a36511565d222206ba25c27ee0b239229f43d620c3d85f230318a78
MD5 1aa25488ec225acd5b57cd482c6005a8
BLAKE2b-256 b29ac67297c3b5187df2586695390f91d15833f6a0456be2de90bcf6ff7c9045

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