X-Git-Url: https://git.madduck.net/etc/vim.git/blobdiff_plain/7395f55564a689a28db5ab3f82c079f7fc40eadf..9a6c88c7f4b4db14631f8dc9e8d44b3aed9d57c9:/black.py?ds=inline diff --git a/black.py b/black.py index 57cd9a6..afc37d9 100644 --- a/black.py +++ b/black.py @@ -46,9 +46,10 @@ from blib2to3.pgen2.parse import ParseError __version__ = "18.5b0" DEFAULT_LINE_LENGTH = 88 +CACHE_DIR = Path(user_cache_dir("black", version=__version__)) + # types -syms = pygram.python_symbols FileContent = str Encoding = str Depth = int @@ -65,6 +66,9 @@ Cache = Dict[Path, CacheInfo] out = partial(click.secho, bold=True, err=True) err = partial(click.secho, fg="red", err=True) +pygram.initialize(CACHE_DIR) +syms = pygram.python_symbols + class NothingChanged(UserWarning): """Raised by :func:`format_file` when reformatted code is the same as source.""" @@ -1371,32 +1375,6 @@ class LineGenerator(Visitor[Line]): yield from self.line() yield from self.visit(child) - def visit_import_from(self, node: Node) -> Iterator[Line]: - """Visit import_from and maybe put invisible parentheses. - - This is separate from `visit_stmt` because import statements don't - support arbitrary atoms and thus handling of parentheses is custom. - """ - check_lpar = False - for index, child in enumerate(node.children): - if check_lpar: - if child.type == token.LPAR: - # make parentheses invisible - child.value = "" # type: ignore - node.children[-1].value = "" # type: ignore - else: - # insert invisible parentheses - node.insert_child(index, Leaf(token.LPAR, "")) - node.append_child(Leaf(token.RPAR, "")) - break - - check_lpar = ( - child.type == token.NAME and child.value == "import" # type: ignore - ) - - for child in node.children: - yield from self.visit(child) - def visit_SEMI(self, leaf: Leaf) -> Iterator[Line]: """Remove a semicolon and put the other statement on a separate line.""" yield from self.line() @@ -1443,6 +1421,7 @@ class LineGenerator(Visitor[Line]): self.visit_classdef = partial(v, keywords={"class"}, parens=Ø) self.visit_expr_stmt = partial(v, keywords=Ø, parens=ASSIGNMENTS) self.visit_return_stmt = partial(v, keywords={"return"}, parens={"return"}) + self.visit_import_from = partial(v, keywords=Ø, parens={"import"}) self.visit_async_funcdef = self.visit_async_stmt self.visit_decorated = self.visit_decorators @@ -1816,7 +1795,7 @@ def is_split_before_delimiter(leaf: Leaf, previous: Leaf = None) -> int: return 0 -def generate_comments(leaf: Leaf) -> Iterator[Leaf]: +def generate_comments(leaf: LN) -> Iterator[Leaf]: """Clean the prefix of the `leaf` and generate comments from it, if any. Comments in lib2to3 are shoved into the whitespace prefix. This happens @@ -2333,8 +2312,13 @@ def normalize_invisible_parens(node: Node, parens_after: Set[str]) -> None: Standardizes on visible parentheses for single-element tuples, and keeps existing visible parentheses for other tuples and generator expressions. """ + try: + list(generate_comments(node)) + except FormatOff: + return # This `node` has a prefix with `# fmt: off`, don't mess with parens. + check_lpar = False - for child in list(node.children): + for index, child in enumerate(list(node.children)): if check_lpar: if child.type == syms.atom: maybe_make_parens_invisible_in_atom(child) @@ -2342,8 +2326,21 @@ def normalize_invisible_parens(node: Node, parens_after: Set[str]) -> None: # wrap child in visible parentheses lpar = Leaf(token.LPAR, "(") rpar = Leaf(token.RPAR, ")") - index = child.remove() or 0 + child.remove() node.insert_child(index, Node(syms.atom, [lpar, child, rpar])) + elif node.type == syms.import_from: + # "import from" nodes store parentheses directly as part of + # the statement + if child.type == token.LPAR: + # make parentheses invisible + child.value = "" # type: ignore + node.children[-1].value = "" # type: ignore + elif child.type != token.STAR: + # insert invisible parentheses + node.insert_child(index, Leaf(token.LPAR, "")) + node.append_child(Leaf(token.RPAR, "")) + break + elif not (isinstance(child, Leaf) and is_multiline_string(child)): # wrap child in invisible parentheses lpar = Leaf(token.LPAR, "") @@ -2602,6 +2599,9 @@ def generate_trailers_to_omit(line: Line, line_length: int) -> Iterator[Set[Leaf if length > line_length: break + if leaf.type == STANDALONE_COMMENT: + break + optional_brackets.discard(id(leaf)) if opening_bracket: if leaf is opening_bracket: @@ -3051,9 +3051,6 @@ def can_omit_invisible_parens(line: Line, line_length: int) -> bool: return False -CACHE_DIR = Path(user_cache_dir("black", version=__version__)) - - def get_cache_file(line_length: int) -> Path: return CACHE_DIR / f"cache.{line_length}.pickle"