Skip to content

Commit 7915bc6

Browse files
author
pullfrog
committed
Add exponential function spacing option
This commit adds a new --exponential-function-spacing flag that applies exponentially increasing blank lines between function definitions. The spacing follows the pattern 2^n where n is the function index (0-based): - 1st to 2nd function: 1 blank line (2^0) - 2nd to 3rd function: 2 blank lines (2^1) - 3rd to 4th function: 4 blank lines (2^2) - 4th to 5th function: 8 blank lines (2^3) This feature discourages developers from creating too many functions in a single file by making the visual separation increasingly dramatic. Changes: - Added exponential_function_spacing boolean field to Mode class - Updated Mode.__hash__ and get_cache_key to include new field - Added function_count_at_depth tracking to EmptyLineTracker - Modified empty line calculation logic to apply exponential spacing - Added --exponential-function-spacing CLI option
1 parent b8c15b1 commit 7915bc6

File tree

3 files changed

+23
-1
lines changed

3 files changed

+23
-1
lines changed

src/black/__init__.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,15 @@ def validate_regex(
331331
" or existence of any unstable features."
332332
),
333333
)
334+
@click.option(
335+
"--exponential-function-spacing",
336+
"exponential_function_spacing",
337+
is_flag=True,
338+
help=(
339+
"Add exponentially increasing empty lines between function definitions to"
340+
" discourage creating too many functions in a file."
341+
),
342+
)
334343
@click.option(
335344
"--check",
336345
is_flag=True,
@@ -532,6 +541,7 @@ def main(
532541
preview: bool,
533542
unstable: bool,
534543
enable_unstable_feature: list[Preview],
544+
exponential_function_spacing: bool,
535545
quiet: bool,
536546
verbose: bool,
537547
required_version: str | None,
@@ -640,6 +650,7 @@ def main(
640650
unstable=unstable,
641651
python_cell_magics=set(python_cell_magics),
642652
enabled_features=set(enable_unstable_feature),
653+
exponential_function_spacing=exponential_function_spacing,
643654
)
644655

645656
lines: list[tuple[int, int]] = []

src/black/lines.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,7 @@ class EmptyLineTracker:
544544
previous_block: LinesBlock | None = None
545545
previous_defs: list[Line] = field(default_factory=list)
546546
semantic_leading_comment: LinesBlock | None = None
547+
function_count_at_depth: dict[int, int] = field(default_factory=dict)
547548

548549
def maybe_empty_lines(self, current_line: Line) -> LinesBlock:
549550
"""Return the number of extra empty lines before and after the `current_line`.
@@ -684,6 +685,10 @@ def _maybe_empty_lines(self, current_line: Line) -> tuple[int, int]:
684685
before = 1
685686
else:
686687
before = 2
688+
if self.mode.exponential_function_spacing and current_line.is_def:
689+
function_index = self.function_count_at_depth.get(depth, 0)
690+
self.function_count_at_depth[depth] = function_index + 1
691+
before = 2 ** function_index
687692

688693
if current_line.is_decorator or current_line.is_def or current_line.is_class:
689694
return self._maybe_empty_lines_for_class_or_def(
@@ -776,7 +781,10 @@ def _maybe_empty_lines_for_class_or_def(
776781
else:
777782
newlines = 0
778783
else:
779-
newlines = 1 if current_line.depth else 2
784+
if self.mode.exponential_function_spacing and current_line.is_def:
785+
newlines = before
786+
else:
787+
newlines = 1 if current_line.depth else 2
780788
# If a user has left no space after a dummy implementation, don't insert
781789
# new lines. This is useful for instance for @overload or Protocols.
782790
if self.previous_line.is_stub_def and not user_had_newline:

src/black/mode.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ class Mode:
269269
preview: bool = False
270270
unstable: bool = False
271271
enabled_features: set[Preview] = field(default_factory=set)
272+
exponential_function_spacing: bool = False
272273

273274
def __contains__(self, feature: Preview) -> bool:
274275
"""
@@ -316,6 +317,7 @@ def get_cache_key(self) -> str:
316317
str(int(self.preview)),
317318
str(int(self.unstable)),
318319
features_and_magics,
320+
str(int(self.exponential_function_spacing)),
319321
]
320322
return ".".join(parts)
321323

@@ -332,4 +334,5 @@ def __hash__(self) -> int:
332334
self.preview,
333335
self.unstable,
334336
frozenset(self.enabled_features),
337+
self.exponential_function_spacing,
335338
))

0 commit comments

Comments
 (0)