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.0

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.0
File Size Uploaded Provenance Actions
spacify-0.1.0.tar.gz 24.1 kB Without provenance Details for spacify-0.1.0.tar.gz

Built distributions (wheels)

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

Total release size: 8.6 MB

Release files / spacify-0.1.0.tar.gz

Download URL spacify-0.1.0.tar.gz
Size 24.1 kB
Tags Source
SHA-256 checksum
How to use checksums
4239181ebeaa50cfd4579322e2808bcd9eebbd5b49553dad48d50ee3321fe70b
BLAKE2b-256 checksum
How to use checksums
9fb31c79a7d702f22ddba513bbb0b393145df1d289268079e1574371ee51bc2e
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.0-py3-none-win_amd64.whl

Download URL spacify-0.1.0-py3-none-win_amd64.whl
Size 1.2 MB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
8f9eb257180b6951f83f71f6e051f3537d3ffb9dbf13da64d33b6b35b5be498a
BLAKE2b-256 checksum
How to use checksums
a34219821694f7b9acdb104841cb68c4561e1d587dca7ab2e02e555e118eb712
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.0-py3-none-musllinux_1_2_x86_64.whl

Download URL spacify-0.1.0-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
f5a1608276aa2e908af6ca200a9f8ba6f8268bf6f212203169db6a18595574d4
BLAKE2b-256 checksum
How to use checksums
01dbe9361cf7bc343bbc022f772b856ee492cf054e8c01451c6ba17eeddcbe79
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.0-py3-none-musllinux_1_2_aarch64.whl

Download URL spacify-0.1.0-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
409527d3db894c3982ea6dc72c5b959b167bccc4d8d2b8b838132b610e074a54
BLAKE2b-256 checksum
How to use checksums
00d0b11401e5e91ac1dbf9c6a1e05ced8514fba0e773c935cc139deec6359cff
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.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL spacify-0.1.0-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
982c7435c305082a7f5e8d97eae2caf6d1a32cb08be140790e877335c5b125f1
BLAKE2b-256 checksum
How to use checksums
3b1d98fc3c11c2fdd1b8b59489f4fdb1e188e9dcbd07cea1b2c8035de1de8b17
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.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL spacify-0.1.0-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
1b5d37b369f7ae2e9c90eee27e18d3570a50813172a9c2e24fb3a6f4b30af902
BLAKE2b-256 checksum
How to use checksums
212d76a755131ea73684f15a9374e98efbac4bc3ff1f4c64bcb3bb627c48b92b
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.0-py3-none-macosx_11_0_arm64.whl

Download URL spacify-0.1.0-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
49cef85b5fe0b5c1e16bf32fe926ff5c1ff2c7d921911e7d022b1067aa98f93b
BLAKE2b-256 checksum
How to use checksums
5fabca3f78844753b62520adcd38e3aa04afd2b1fe3c21f22177245dba11d0bf
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.0-py3-none-macosx_10_12_x86_64.whl

Download URL spacify-0.1.0-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
19b05a42617f6d32b3e694f729b07df790604e7d5d822d78219c4edea8b946fb
BLAKE2b-256 checksum
How to use checksums
e1d80c04357dbc2466e02a8db64ba4104ac88fde9f438215769df8882ed59733
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.0

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