]>
git.madduck.net Git - etc/vim.git/blobdiff - src/black/lines.py
madduck's git repository
Every one of the projects in this repository is available at the canonical
URL git://git.madduck.net/madduck/pub/<projectpath> — see
each project's metadata for the exact URL.
All patches and comments are welcome. Please squash your changes to logical
commits before using git-format-patch and git-send-email to
patches@ git. madduck. net .
If you'd read over the Git project's submission guidelines and adhered to them,
I'd be especially grateful.
SSH access, as well as push access can be individually
arranged .
If you use my repositories frequently, consider adding the following
snippet to ~/.gitconfig and using the third clone URL listed for each
project:
[url "git://git.madduck.net/madduck/"]
insteadOf = madduck:
is_multiline_string,
is_one_sequence_between,
is_type_comment,
is_multiline_string,
is_one_sequence_between,
is_type_comment,
+ is_type_ignore_comment,
is_with_or_async_with_stmt,
replace_child,
syms,
is_with_or_async_with_stmt,
replace_child,
syms,
class Line:
"""Holds leaves and comments. Can be printed with `str(line)`."""
class Line:
"""Holds leaves and comments. Can be printed with `str(line)`."""
+ mode: Mode = field(repr=False)
depth: int = 0
leaves: List[Leaf] = field(default_factory=list)
# keys ordered like `leaves`
depth: int = 0
leaves: List[Leaf] = field(default_factory=list)
# keys ordered like `leaves`
# Note: at this point leaf.prefix should be empty except for
# imports, for which we only preserve newlines.
leaf.prefix += whitespace(
# Note: at this point leaf.prefix should be empty except for
# imports, for which we only preserve newlines.
leaf.prefix += whitespace(
- leaf, complex_subscript=self.is_complex_subscript(leaf)
+ leaf,
+ complex_subscript=self.is_complex_subscript(leaf),
+ mode=self.mode,
)
if self.inside_brackets or not preformatted or track_bracket:
self.bracket_tracker.mark(leaf)
)
if self.inside_brackets or not preformatted or track_bracket:
self.bracket_tracker.mark(leaf)
and second_leaf.value == "def"
)
and second_leaf.value == "def"
)
+ @property
+ def is_stub_def(self) -> bool:
+ """Is this line a function definition with a body consisting only of "..."?"""
+ return self.is_def and self.leaves[-4:] == [Leaf(token.COLON, ":")] + [
+ Leaf(token.DOT, ".") for _ in range(3)
+ ]
+
@property
def is_class_paren_empty(self) -> bool:
"""Is this a class with no base classes but using parentheses?
@property
def is_class_paren_empty(self) -> bool:
"""Is this a class with no base classes but using parentheses?
@property
def is_triple_quoted_string(self) -> bool:
"""Is the line a triple quoted string?"""
@property
def is_triple_quoted_string(self) -> bool:
"""Is the line a triple quoted string?"""
- return (
- bool(self)
- and self.leaves[0].type == token.STRING
- and self.leaves[0].value.startswith(('"""', "'''"))
- )
+ if not self or self.leaves[0].type != token.STRING:
+ return False
+ value = self.leaves[0].value
+ if value.startswith(('"""', "'''")):
+ return True
+ if Preview.accept_raw_docstrings in self.mode and value.startswith(
+ ("r'''", 'r"""', "R'''", 'R"""')
+ ):
+ return True
+ return False
@property
def opens_block(self) -> bool:
@property
def opens_block(self) -> bool:
for comment in comments:
if is_type_comment(comment):
if comment_seen or (
for comment in comments:
if is_type_comment(comment):
if comment_seen or (
- not is_type_comment(comment, " ignore" )
+ not is_type_ignore_comment(comment )
and leaf_id not in ignored_ids
):
return True
and leaf_id not in ignored_ids
):
return True
# line.
for node in self.leaves[-2:]:
for comment in self.comments.get(id(node), []):
# line.
for node in self.leaves[-2:]:
for comment in self.comments.get(id(node), []):
- if is_type_comment(comment, " ignore" ):
+ if is_type_ignore_comment(comment ):
if self.previous_line is None
else before - previous_after
)
if self.previous_line is None
else before - previous_after
)
+ if (
+ Preview.module_docstring_newlines in current_line.mode
+ and self.previous_block
+ and self.previous_block.previous_block is None
+ and len(self.previous_block.original_line.leaves) == 1
+ and self.previous_block.original_line.is_triple_quoted_string
+ ):
+ before = 1
+
block = LinesBlock(
mode=self.mode,
previous_block=self.previous_block,
block = LinesBlock(
mode=self.mode,
previous_block=self.previous_block,
first_leaf.prefix = ""
else:
before = 0
first_leaf.prefix = ""
else:
before = 0
+
+ user_had_newline = bool(before)
depth = current_line.depth
depth = current_line.depth
while self.previous_defs and self.previous_defs[-1].depth >= depth:
while self.previous_defs and self.previous_defs[-1].depth >= depth:
+ previous_def = self.previous_defs.pop()
+
+ if previous_def is not None:
+ assert self.previous_line is not None
- assert self.previous_line is not None
if depth and not current_line.is_def and self.previous_line.is_def:
# Empty lines between attributes and methods should be preserved.
if depth and not current_line.is_def and self.previous_line.is_def:
# Empty lines between attributes and methods should be preserved.
- before = min(1, before)
+ before = 1 if user_had_newline else 0
elif (
Preview.blank_line_after_nested_stub_class in self.mode
elif (
Preview.blank_line_after_nested_stub_class in self.mode
- and self.previous_defs[-1] .is_class
- and not self.previous_defs[-1] .is_stub_class
+ and previous_def .is_class
+ and not previous_def .is_stub_class
):
before = 1
elif depth:
):
before = 1
elif depth:
before = 1
elif (
not depth
before = 1
elif (
not depth
- and self.previous_defs[-1] .depth
and current_line.leaves[-1].type == token.COLON
and (
current_line.leaves[0].value
and current_line.leaves[-1].type == token.COLON
and (
current_line.leaves[0].value
before = 1
else:
before = 2
before = 1
else:
before = 2
- self.previous_defs.pop()
if current_line.is_decorator or current_line.is_def or current_line.is_class:
if current_line.is_decorator or current_line.is_def or current_line.is_class:
- return self._maybe_empty_lines_for_class_or_def(current_line, before)
+ return self._maybe_empty_lines_for_class_or_def(
+ current_line, before, user_had_newline
+ )
and self.previous_line.is_class
and current_line.is_triple_quoted_string
):
and self.previous_line.is_class
and current_line.is_triple_quoted_string
):
+ if Preview.no_blank_line_before_class_docstring in current_line.mode:
+ return 0, 1
return before, 1
if self.previous_line and self.previous_line.opens_block:
return 0, 0
return before, 0
return before, 1
if self.previous_line and self.previous_line.opens_block:
return 0, 0
return before, 0
- def _maybe_empty_lines_for_class_or_def(
- self, current_line: Line, before: int
+ def _maybe_empty_lines_for_class_or_def( # noqa: C901
+ self, current_line: Line, before: int, user_had_newline: bool
) -> Tuple[int, int]:
if not current_line.is_decorator:
self.previous_defs.append(current_line)
) -> Tuple[int, int]:
if not current_line.is_decorator:
self.previous_defs.append(current_line)
newlines = 0
else:
newlines = 1
newlines = 0
else:
newlines = 1
+ # Remove case `self.previous_line.depth > current_line.depth` below when
+ # this becomes stable.
+ #
+ # Don't inspect the previous line if it's part of the body of the previous
+ # statement in the same level, we always want a blank line if there's
+ # something with a body preceding.
+ elif (
+ Preview.blank_line_between_nested_and_def_stub_file in current_line.mode
+ and self.previous_line.depth > current_line.depth
+ ):
+ newlines = 1
elif (
current_line.is_def or current_line.is_decorator
) and not self.previous_line.is_def:
elif (
current_line.is_def or current_line.is_decorator
) and not self.previous_line.is_def:
newlines = 0
else:
newlines = 1 if current_line.depth else 2
newlines = 0
else:
newlines = 1 if current_line.depth else 2
+ # If a user has left no space after a dummy implementation, don't insert
+ # new lines. This is useful for instance for @overload or Protocols.
+ if (
+ Preview.dummy_implementations in self.mode
+ and self.previous_line.is_stub_def
+ and not user_had_newline
+ ):
+ newlines = 0
if comment_to_add_newlines is not None:
previous_block = comment_to_add_newlines.previous_block
if previous_block is not None:
if comment_to_add_newlines is not None:
previous_block = comment_to_add_newlines.previous_block
if previous_block is not None: