Reusable Rattle rules for blank-line and statement cuddling policies.
Project description
rattle-blank-lines
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
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rattle_blank_lines-0.2.5.tar.gz.
File metadata
- Download URL: rattle_blank_lines-0.2.5.tar.gz
- Upload date:
- Size: 75.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dd558e9a3ca1f3e7f5ccf61323948fb38ae180109ff03ad9688bd474df2369f7
|
|
| MD5 |
d141197a74f77982521188d33add5e41
|
|
| BLAKE2b-256 |
c6bfde793e9efb63ee692f3e3931b48df992d99055778871cca5164aaef484d3
|
File details
Details for the file rattle_blank_lines-0.2.5-py3-none-any.whl.
File metadata
- Download URL: rattle_blank_lines-0.2.5-py3-none-any.whl
- Upload date:
- Size: 27.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fea1bd7922d4fea27a542c23b436d63abd0a11294df63a28cd34f546e5d4b433
|
|
| MD5 |
c804f6db924587b204731a27d3d85352
|
|
| BLAKE2b-256 |
c060c4ee891d479baac324b898d8798ab016f335c2d3b09ef12fbfa97f1aefbf
|