Skip to main content

Reusable Rattle rules for blank-line and statement cuddling policies.

Project description

rattle-blank-lines

Tests PyPI version Supported versions Downloads license

Rattle rules for blank-line and statement-cuddling policy checks in Python.

Installation

pip install rattle-blank-lines
uv add rattle-blank-lines

Quick Start

Add the rule pack to your project configuration:

[tool.rattle]
root = true
enable = ["rattle_blank_lines.rules"]

This adds the rattle_blank_lines rules.

Run linting and autofix:

rattle lint <path>
rattle lint --diff <path>
rattle fix <path>

For in-file suppressions, use Rattle comments:

  • # lint-ignore: BlankLineBeforeAssignment
  • # lint-fixme: BlankLineBeforeAssignment

Rules

NoSuiteLeadingTrailingBlankLines

Removes leading and trailing blank lines at suite boundaries.

Before:

def f() -> int:

    value = 1
    return value

After:

def f() -> int:
    value = 1
    return value

BlankLineBeforeBranchInLargeSuite

Requires a blank line before return/raise/break/continue in larger suites.

Before:

def f(value: int) -> int:
    x = value + 1
    y = x + 1
    z = y + 1
    return z

After:

def f(value: int) -> int:
    x = value + 1
    y = x + 1
    z = y + 1

    return z

BlockHeaderCuddleRelaxed

Allows cuddling before a block when the setup still belongs to the same step. The first statement after a suite docstring is exempt.

Before:

def f(value: int) -> int:
    prepared = value + 1
    if value > 0:
        return value

    return 0

After:

def f(value: int) -> int:
    prepared = value + 1

    if value > 0:
        return value

    return 0

Also allowed:

def f(override_name: str | None) -> str:
    display_name = "guest"
    if override_name is not None:
        display_name = override_name
    return display_name
def f(slots: dict[str, int], key: str) -> None:
    slots[key] -= 1
    if slots[key] < 0:
        raise ValueError(key)

BlockHeaderCuddleStrict

Stricter cuddle mode. The first statement after a suite docstring is exempt.

Opt in with rattle_blank_lines.rules.block_header_cuddle_strict, and disable BlockHeaderCuddleRelaxed if you want strict mode instead of relaxed mode.

[tool.rattle]
root = true
enable = [
  "rattle_blank_lines.rules",
  "rattle_blank_lines.rules.block_header_cuddle_strict",
]
disable = [
  "BlockHeaderCuddleRelaxed",
]

Before:

def f(value: int) -> int:
    header_value = value + 1
    trailing = value + 2
    if header_value > 0:
        return header_value

    return 0

After:

def f(value: int) -> int:
    header_value = value + 1
    trailing = value + 2

    if header_value > 0:
        return header_value

    return 0

BlankLineAfterControlBlock

Requires a blank line after multiline control-flow blocks. Some compact patterns stay together, such as guard ladders, with pytest.raises(...) clusters, and immediate inspection after with.

Before:

def f(value: int) -> int:
    if value > 0:
        value += 1
    return value

After:

def f(value: int) -> int:
    if value > 0:
        value += 1

    return value

BlankLineBeforeAssignment

Requires a blank line before an assignment after a non-assignment statement.

Before:

def f(candidate: object) -> object:
    validate(candidate)
    display_value = str(candidate)
    if supports_live_interaction():
        highlight(candidate)
    return candidate

Usually:

def f(candidate: object) -> object:
    validate(candidate)

    display_value = str(candidate)
    if supports_live_interaction():
        highlight(candidate)
    return candidate

Also allowed:

def f() -> int:
    log_start()
    value = compute()
    return value

Also allowed:

def configure_logger(logger: logging.Logger, handler: logging.Handler) -> None:
    logger.addHandler(handler)
    logger.propagate = False

MatchCaseSeparation

Requires a blank line before the next case after a larger case body.

This rule is opt-in and is not included by enable = ["rattle_blank_lines.rules"]. You can enable it with enable = ["rattle_blank_lines.rules.match_case_separation"].

Before:

def f(value: int) -> int:
    match value:
        case 1:
            a = 1
            b = 2
            c = 3
        case _:
            return 0

Rule Options

[tool.rattle.options]

[tool.rattle.options.BlankLineBeforeBranchInLargeSuite]
max_suite_non_empty_lines = 2
compact_tail_max_statements = 2
allow_related_return_tails = true
allow_guard_ladder_final_branch = true

[tool.rattle.options.BlankLineBeforeAssignment]
short_control_flow_max_statements = 3
related_use_lookahead = 2
allow_local_helper_capture = true
allow_post_guard_continuation = true

[tool.rattle.options.BlockHeaderCuddleRelaxed]
body_usage_lookahead = 4
setup_run_lookback = 3
allow_setup_before_compact_guard_ladder = true

[tool.rattle.options.BlankLineAfterControlBlock]
related_use_lookahead = 2
allow_compact_guard_ladders = true
allow_pytest_raises_clusters = true
allow_with_immediate_inspection = true

[tool.rattle.options.MatchCaseSeparation]
max_case_non_empty_lines = 2

After:

def f(value: int) -> int:
    match value:
        case 1:
            a = 1
            b = 2
            c = 3

        case _:
            return 0

License

MIT

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

rattle_blank_lines-0.3.0.tar.gz (85.8 kB view details)

Uploaded Source

Built Distribution

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

rattle_blank_lines-0.3.0-py3-none-any.whl (27.5 kB view details)

Uploaded Python 3

File details

Details for the file rattle_blank_lines-0.3.0.tar.gz.

File metadata

  • Download URL: rattle_blank_lines-0.3.0.tar.gz
  • Upload date:
  • Size: 85.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for rattle_blank_lines-0.3.0.tar.gz
Algorithm Hash digest
SHA256 a9d66d9375546ae4193c1a9aa7d73138120b4867e35031e7baeaf38ca64894af
MD5 8ab195d9865055c2d35c14d066dc4c22
BLAKE2b-256 bb7884e45aa6611b58c1464e34b917433b76fd329832112515a0c11522849018

See more details on using hashes here.

File details

Details for the file rattle_blank_lines-0.3.0-py3-none-any.whl.

File metadata

File hashes

Hashes for rattle_blank_lines-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3ec0a430abc31f4bef377093a7f34a20f79390d3204158778831bfb1e5e23d2a
MD5 83c776ed0f38d7a224f476bc6d7dc051
BLAKE2b-256 120c30c8a8ac5106c852f5cb9cd7dc3e2c5bd7874895c0d61b86bd32f28bcf90

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