Skip to main content

spacify

CI PyPI

A fast formatter for the vertical rhythm of Python code. ruff format decides how a statement is laid out, but leaves most of the blank lines between statements up to you. spacify fills that gap: it puts air around logical blocks and tightens runs of related statements, and it only touches the blank lines between statements.

Before:

def load(paths):
    seen = set()
    for path in paths:
        if path in seen:
            continue
        seen.add(path)
    total = len(seen)

    count = 0
    log(total)
    return total

After spacify:

def load(paths):
    seen = set()

    for path in paths:
        if path in seen:
            continue

        seen.add(path)

    total = len(seen)
    count = 0
    log(total)

    return total

spacify never fights ruff. Every rule stays inside the blank-line bounds ruff format keeps, and CI runs both tools over CPython's standard library in both orders to check they reach a fixed point. Checking all of CPython's Lib takes under half a second on 8 cores.

Install

uv tool install spacify    # or: pipx install spacify, pip install spacify

Use with prek or pre-commit

Put the hook after ruff-format, so spacify sees ruff's line wrapping:

repos:
  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.16.9
    hooks:
      - id: ruff-format
  - repo: https://github.com/avanserv/spacify-pre-commit
    rev: v0.1.0
    hooks:
      - id: spacify

The hook installs the prebuilt wheel from PyPI, so you don't need a Rust toolchain.

Command line

spacify                   # format every Python file under the current directory
spacify src/ tests/a.py   # format these paths
spacify --check           # write nothing; exit 1 if any file would change
spacify --diff            # write nothing; print a unified diff
spacify - < a.py          # read stdin, write stdout (--stdin-filename names it)

The exit code is 0 on success, 1 when --check or --diff found changes, and 2 on an error such as a syntax error, in which case the file is left untouched. Directory walks respect .gitignore and skip the directories ruff skips by default. A file you name explicitly is always formatted, unless you also pass --force-exclude, which is what the hook does.

Rules

Each rule can be turned on or off. They all apply to sibling statements in the same block.

Rule Effect
blank-before-block At least one blank line before if, for, while, try, with and match (including the async forms) when another statement comes before them.
blank-after-block At least one blank line after one of those blocks, before the next statement.
blank-before-exit At least one blank line before return, raise, break, continue and a bare yield, in blocks of exit-min-block-statements (default 3) or more statements.
collapse-groups No blank line between two single-line statements of the same kind: assignments, augmented assignments, calls, del, assert, global/nonlocal.

The added blank lines take priority over collapse-groups. A few places are never touched:

  • Gaps next to a def or class, after an import, or after a docstring. Ruff decides these.
  • Blank lines that have a comment in the gap, because a comment marks a paragraph you meant. When a rule does add a blank line, it goes above the comments that belong to the next statement.
  • Regions between # fmt: off and # fmt: on (or # spacify: off and # spacify: on), and any line marked # fmt: skip.

Imports are never collapsed, because ruff's isort rules separate import sections with blank lines. A nested block never gets more than one blank line in a row. At module level the limit is two, or one in a .pyi stub.

Configuration

spacify reads [tool.spacify] from pyproject.toml, or the top level of a spacify.toml or .spacify.toml. It uses the first one it finds walking up from the current directory, or the file you pass with --config.

[tool.spacify]
extend-exclude = ["generated", "migrations/*.py"]  # `exclude = [...]` replaces the defaults

[tool.spacify.rules]
blank-before-block = true
blank-after-block = true
blank-before-exit = true
exit-min-block-statements = 3
collapse-groups = true

An exclude pattern containing a / matches the path relative to the config file. Any other pattern matches a single file or directory name.

Contributing

See CONTRIBUTING.md.

Metadata

Release files for spacify 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for spacify 0.1.1
File Size Uploaded Provenance Actions
spacify-0.1.1.tar.gz 24.2 kB Without provenance Details for spacify-0.1.1.tar.gz

Built distributions (wheels)

Table of built distributions (wheels) for spacify 0.1.1
File Actions
spacify-0.1.1-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details for spacify-0.1.1-py3-none-win_amd64.whl
spacify-0.1.1-py3-none-musllinux_1_2_x86_64.whl Python 3 none Linux musl 1.2+ x86-64 Details for spacify-0.1.1-py3-none-musllinux_1_2_x86_64.whl
spacify-0.1.1-py3-none-musllinux_1_2_aarch64.whl Python 3 none Linux musl 1.2+ ARM64 Details for spacify-0.1.1-py3-none-musllinux_1_2_aarch64.whl
spacify-0.1.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl Python 3 none Linux glibc 2.17+ x86-64 Details for spacify-0.1.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
spacify-0.1.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl Python 3 none Linux glibc 2.17+ ARM64 Details for spacify-0.1.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
spacify-0.1.1-py3-none-macosx_11_0_arm64.whl Python 3 none macOS 11.0+ ARM64 Details for spacify-0.1.1-py3-none-macosx_11_0_arm64.whl
spacify-0.1.1-py3-none-macosx_10_12_x86_64.whl Python 3 none macOS 10.12+ x86-64 Details for spacify-0.1.1-py3-none-macosx_10_12_x86_64.whl

Total release size: 8.6 MB

Release files / spacify-0.1.1.tar.gz

Download URL spacify-0.1.1.tar.gz
Size 24.2 kB
Tags Source
SHA-256 checksum
How to use checksums
f4e5e9df6da0a9f752e006f551a868cf673d8c39508159059d12e9ad3c78b7e4
BLAKE2b-256 checksum
How to use checksums
f0500285db1287b99a3d728c49601d550235be5a1a2ef920580257b99b5018c6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / spacify-0.1.1-py3-none-win_amd64.whl

Download URL spacify-0.1.1-py3-none-win_amd64.whl
Size 1.2 MB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
5a411fd87938ded7d9638f0c8883a1f49b89b727e94cc70b9c64f2acee30ba58
BLAKE2b-256 checksum
How to use checksums
2ec6fbd47166123829e94a7377ac2402ef02cd714b8ca514f67b9ff5cb59f4f4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / spacify-0.1.1-py3-none-musllinux_1_2_x86_64.whl

Download URL spacify-0.1.1-py3-none-musllinux_1_2_x86_64.whl
Size 1.4 MB
Tags Linux musl 1.2+ x86-64 Python 3
SHA-256 checksum
How to use checksums
befc4b19d51f6346341bcb1f323a55169b54ba4ed7ab0e78f796a1afc4dc3707
BLAKE2b-256 checksum
How to use checksums
38cf9372821e00ff908ec0bf9eac908ca84a3cff84937db9ead966c3966c4595
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / spacify-0.1.1-py3-none-musllinux_1_2_aarch64.whl

Download URL spacify-0.1.1-py3-none-musllinux_1_2_aarch64.whl
Size 1.2 MB
Tags Linux musl 1.2+ ARM64 Python 3
SHA-256 checksum
How to use checksums
bd2455475ec48b02abbe5d27d5f642d9c9fb4870b999e2962573eedb7303dad4
BLAKE2b-256 checksum
How to use checksums
db726232993a8c7a2bf6297477a2e3511229467aff2116669223e8dfa654a6b2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / spacify-0.1.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL spacify-0.1.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 1.3 MB
Tags Linux glibc 2.17+ x86-64 Python 3
SHA-256 checksum
How to use checksums
712655f76a2860d7d6c020c93414105ad4c7bd682042978158299ffeec617466
BLAKE2b-256 checksum
How to use checksums
337d564443ea58a24148b4346c4794fb0d18f8a2d7609fbe064706639ff87814
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / spacify-0.1.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL spacify-0.1.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 1.2 MB
Tags Linux glibc 2.17+ ARM64 Python 3
SHA-256 checksum
How to use checksums
2410924193a6a655a4d1c6587360c7eb2184aaaeac66492a88ef4a1cd6f89e61
BLAKE2b-256 checksum
How to use checksums
a66a45c6be35e36fbd39be1f74e53273ecf287039b7ada344dbc8595ad9abd70
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / spacify-0.1.1-py3-none-macosx_11_0_arm64.whl

Download URL spacify-0.1.1-py3-none-macosx_11_0_arm64.whl
Size 1.1 MB
Tags Python 3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
a83dfe1415924a2c40cc77bef38a46825535fe39b967d18ecfdd23f9d8a204cc
BLAKE2b-256 checksum
How to use checksums
14f36c7c61af05504e67c5b0d9f97938d3a4994d1f67b6fce8773965e6235e72
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / spacify-0.1.1-py3-none-macosx_10_12_x86_64.whl

Download URL spacify-0.1.1-py3-none-macosx_10_12_x86_64.whl
Size 1.2 MB
Tags Python 3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
8a9797ca9d95cb4417ab49d3e5f49882dc6e64e57958383dfb5b38ec239d41ee
BLAKE2b-256 checksum
How to use checksums
231f7f601d817bd499c6209b1db92b22afe83df4aca882447022574fd18f1878
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for spacify 0.1.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page