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. Rattle's built-in rattle.rules stay enabled unless you disable them.

If you want to run only rattle_blank_lines, also set disable = ["rattle.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 (BL100, BL101)

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 (BL200)

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 (BL300)

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 (BL301)

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

Opt in with rattle_blank_lines.rules.block_header_cuddle_strict:BlockHeaderCuddleStrict, and disable BlockHeaderCuddleRelaxed if you want BL301 instead of BL300.

[tool.rattle]
root = true
enable = [
  "rattle_blank_lines.rules",
  "rattle_blank_lines.rules.block_header_cuddle_strict:BlockHeaderCuddleStrict",
]
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 (BL350)

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 (BL210)

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 (BL400)

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:MatchCaseSeparation"].

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.2.6.tar.gz (76.7 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.2.6-py3-none-any.whl (27.8 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: rattle_blank_lines-0.2.6.tar.gz
  • Upload date:
  • Size: 76.7 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.2.6.tar.gz
Algorithm Hash digest
SHA256 1b4f44e9b1ac6f39b05b92b79e80b02241fb70fafede0cbd076f59ab60e58f75
MD5 3b038d3033b1b462c97f537043e2495f
BLAKE2b-256 58f2f87591707a9a05245aa19cb2daa82f33c939183dbb7519e59cc683e00743

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for rattle_blank_lines-0.2.6-py3-none-any.whl
Algorithm Hash digest
SHA256 9f7e28a9299ac6c5efae7a13e91b92a297610324c49e5e6d5700581f8fde55b7
MD5 edd9a0b69fc61bbd49f001dc3d4aa7ef
BLAKE2b-256 0d9596fdea16f620695fd2eab011cd2ae252dc85d939d60ce087c1b78be9e255

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