]>
git.madduck.net Git - etc/vim.git/blobdiff - src/black/linegen.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:
import sys
from typing import Collection, Iterator, List, Optional, Set, Union
import sys
from typing import Collection, Iterator, List, Optional, Set, Union
-from dataclasses import dataclass, field
-
from black.nodes import WHITESPACE, RARROW, STATEMENT, STANDALONE_COMMENT
from black.nodes import ASSIGNMENTS, OPENING_BRACKETS, CLOSING_BRACKETS
from black.nodes import Visitor, syms, first_child_is_arith, ensure_visible
from black.nodes import WHITESPACE, RARROW, STATEMENT, STANDALONE_COMMENT
from black.nodes import ASSIGNMENTS, OPENING_BRACKETS, CLOSING_BRACKETS
from black.nodes import Visitor, syms, first_child_is_arith, ensure_visible
"""A readable split that fits the allotted line length is impossible."""
"""A readable split that fits the allotted line length is impossible."""
+# This isn't a dataclass because @dataclass + Generic breaks mypyc.
+# See also https://github.com/mypyc/mypyc/issues/827.
class LineGenerator(Visitor[Line]):
"""Generates reformatted Line objects. Empty lines are not emitted.
class LineGenerator(Visitor[Line]):
"""Generates reformatted Line objects. Empty lines are not emitted.
in ways that will no longer stringify to valid Python code on the tree.
"""
in ways that will no longer stringify to valid Python code on the tree.
"""
- mode: Mode
- remove_u_prefix: bool = False
- current_line: Line = field(init=False)
+ def __init__(self, mode: Mode, remove_u_prefix: bool = False) -> None:
+ self.mode = mode
+ self.remove_u_prefix = remove_u_prefix
+ self.current_line: Line
+ self.__post_init__()
def line(self, indent: int = 0) -> Iterator[Line]:
"""Generate a line.
def line(self, indent: int = 0) -> Iterator[Line]:
"""Generate a line.
"""Visit a statement.
This implementation is shared for `if`, `while`, `for`, `try`, `except`,
"""Visit a statement.
This implementation is shared for `if`, `while`, `for`, `try`, `except`,
- `def`, `with`, `class`, `assert` and assignments.
+ `def`, `with`, `class`, `assert`, `match`, `case` and assignments.
The relevant Python language `keywords` for a given statement will be
NAME leaves within it. This methods puts those on a separate line.
The relevant Python language `keywords` for a given statement will be
NAME leaves within it. This methods puts those on a separate line.
self.visit_async_funcdef = self.visit_async_stmt
self.visit_decorated = self.visit_decorators
self.visit_async_funcdef = self.visit_async_stmt
self.visit_decorated = self.visit_decorators
+ # PEP 634
+ self.visit_match_stmt = partial(v, keywords={"match"}, parens=Ø)
+ self.visit_case_block = partial(v, keywords={"case"}, parens=Ø)
+
def transform_line(
line: Line, mode: Mode, features: Collection[Feature] = ()
def transform_line(
line: Line, mode: Mode, features: Collection[Feature] = ()
transformers = [left_hand_split]
else:
transformers = [left_hand_split]
else:
- def rhs(line: Line, features: Collection[Feature]) -> Iterator[Line]:
+ def _rhs(
+ self: object, line: Line, features: Collection[Feature]
+ ) -> Iterator[Line]:
"""Wraps calls to `right_hand_split`.
The calls increasingly `omit` right-hand trailers (bracket pairs with
"""Wraps calls to `right_hand_split`.
The calls increasingly `omit` right-hand trailers (bracket pairs with
line, line_length=mode.line_length, features=features
)
line, line_length=mode.line_length, features=features
)
+ # HACK: nested functions (like _rhs) compiled by mypyc don't retain their
+ # __name__ attribute which is needed in `run_transformer` further down.
+ # Unfortunately a nested class breaks mypyc too. So a class must be created
+ # via type ... https://github.com/mypyc/mypyc/issues/884
+ rhs = type("rhs", (), {"__call__": _rhs})()
+
if mode.experimental_string_processing:
if line.inside_brackets:
transformers = [
if mode.experimental_string_processing:
if line.inside_brackets:
transformers = [
yield from right_hand_split(line, line_length, features=features, omit=omit)
return
yield from right_hand_split(line, line_length, features=features, omit=omit)
return
+ except CannotSplit as e :
if not (
can_be_split(body)
or is_line_short_enough(body, line_length=line_length)
):
raise CannotSplit(
"Splitting failed, body is still too long and can't be split."
if not (
can_be_split(body)
or is_line_short_enough(body, line_length=line_length)
):
raise CannotSplit(
"Splitting failed, body is still too long and can't be split."
elif head.contains_multiline_strings() or tail.contains_multiline_strings():
raise CannotSplit(
elif head.contains_multiline_strings() or tail.contains_multiline_strings():
raise CannotSplit(
" satisfy the splitting algorithm because the head or the tail"
" contains multiline strings which by definition never fit one"
" line."
" satisfy the splitting algorithm because the head or the tail"
" contains multiline strings which by definition never fit one"
" line."
ensure_visible(opening_bracket)
ensure_visible(closing_bracket)
ensure_visible(opening_bracket)
ensure_visible(closing_bracket)
try:
last_leaf = line.leaves[-1]
except IndexError:
try:
last_leaf = line.leaves[-1]
except IndexError:
- raise CannotSplit("Line empty")
+ raise CannotSplit("Line empty") from None
bt = line.bracket_tracker
try:
delimiter_priority = bt.max_delimiter_priority(exclude={id(last_leaf)})
except ValueError:
bt = line.bracket_tracker
try:
delimiter_priority = bt.max_delimiter_priority(exclude={id(last_leaf)})
except ValueError:
- raise CannotSplit("No delimiters found")
+ raise CannotSplit("No delimiters found") from None
if delimiter_priority == DOT_PRIORITY:
if bt.delimiter_count_with_priority(delimiter_priority) == 1:
if delimiter_priority == DOT_PRIORITY:
if bt.delimiter_count_with_priority(delimiter_priority) == 1:
result.extend(transform_line(transformed_line, mode=mode, features=features))
if (
result.extend(transform_line(transformed_line, mode=mode, features=features))
if (
- transform.__name__ != "rhs"
+ transform.__class__.__ name__ != "rhs"
or not line.bracket_tracker.invisible
or any(bracket.value for bracket in line.bracket_tracker.invisible)
or line.contains_multiline_strings()
or not line.bracket_tracker.invisible
or any(bracket.value for bracket in line.bracket_tracker.invisible)
or line.contains_multiline_strings()