Fix invalid code on stars in long from-imports being wrapped in parentheses
Fixes #234
This commit is contained in:
parent
808754af18
commit
9a6c88c7f4
@ -661,6 +661,8 @@ More details can be found in [CONTRIBUTING](CONTRIBUTING.md).
|
|||||||
|
|
||||||
* fixed optional parentheses being removed within `# fmt: off` sections (#224)
|
* fixed optional parentheses being removed within `# fmt: off` sections (#224)
|
||||||
|
|
||||||
|
* fixed invalid code produced when stars in very long imports were incorrectly
|
||||||
|
wrapped in optional parentheses (#234)
|
||||||
|
|
||||||
### 18.5b0
|
### 18.5b0
|
||||||
|
|
||||||
|
44
black.py
44
black.py
@ -1375,32 +1375,6 @@ def visit_decorators(self, node: Node) -> Iterator[Line]:
|
|||||||
yield from self.line()
|
yield from self.line()
|
||||||
yield from self.visit(child)
|
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]:
|
def visit_SEMI(self, leaf: Leaf) -> Iterator[Line]:
|
||||||
"""Remove a semicolon and put the other statement on a separate line."""
|
"""Remove a semicolon and put the other statement on a separate line."""
|
||||||
yield from self.line()
|
yield from self.line()
|
||||||
@ -1447,6 +1421,7 @@ def __attrs_post_init__(self) -> None:
|
|||||||
self.visit_classdef = partial(v, keywords={"class"}, parens=Ø)
|
self.visit_classdef = partial(v, keywords={"class"}, parens=Ø)
|
||||||
self.visit_expr_stmt = partial(v, keywords=Ø, parens=ASSIGNMENTS)
|
self.visit_expr_stmt = partial(v, keywords=Ø, parens=ASSIGNMENTS)
|
||||||
self.visit_return_stmt = partial(v, keywords={"return"}, parens={"return"})
|
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_async_funcdef = self.visit_async_stmt
|
||||||
self.visit_decorated = self.visit_decorators
|
self.visit_decorated = self.visit_decorators
|
||||||
|
|
||||||
@ -2343,7 +2318,7 @@ def normalize_invisible_parens(node: Node, parens_after: Set[str]) -> None:
|
|||||||
return # This `node` has a prefix with `# fmt: off`, don't mess with parens.
|
return # This `node` has a prefix with `# fmt: off`, don't mess with parens.
|
||||||
|
|
||||||
check_lpar = False
|
check_lpar = False
|
||||||
for child in list(node.children):
|
for index, child in enumerate(list(node.children)):
|
||||||
if check_lpar:
|
if check_lpar:
|
||||||
if child.type == syms.atom:
|
if child.type == syms.atom:
|
||||||
maybe_make_parens_invisible_in_atom(child)
|
maybe_make_parens_invisible_in_atom(child)
|
||||||
@ -2351,8 +2326,21 @@ def normalize_invisible_parens(node: Node, parens_after: Set[str]) -> None:
|
|||||||
# wrap child in visible parentheses
|
# wrap child in visible parentheses
|
||||||
lpar = Leaf(token.LPAR, "(")
|
lpar = Leaf(token.LPAR, "(")
|
||||||
rpar = Leaf(token.RPAR, ")")
|
rpar = Leaf(token.RPAR, ")")
|
||||||
index = child.remove() or 0
|
child.remove()
|
||||||
node.insert_child(index, Node(syms.atom, [lpar, child, rpar]))
|
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)):
|
elif not (isinstance(child, Leaf) and is_multiline_string(child)):
|
||||||
# wrap child in invisible parentheses
|
# wrap child in invisible parentheses
|
||||||
lpar = Leaf(token.LPAR, "")
|
lpar = Leaf(token.LPAR, "")
|
||||||
|
@ -6,6 +6,10 @@
|
|||||||
|
|
||||||
from library import some_connection, \
|
from library import some_connection, \
|
||||||
some_decorator
|
some_decorator
|
||||||
|
# fmt: off
|
||||||
|
from third_party import (X,
|
||||||
|
Y, Z)
|
||||||
|
# fmt: on
|
||||||
f'trigger 3.6 mode'
|
f'trigger 3.6 mode'
|
||||||
# fmt: off
|
# fmt: off
|
||||||
def func_no_args():
|
def func_no_args():
|
||||||
@ -102,6 +106,10 @@ def single_literal_yapf_disable():
|
|||||||
|
|
||||||
from library import some_connection, some_decorator
|
from library import some_connection, some_decorator
|
||||||
|
|
||||||
|
# fmt: off
|
||||||
|
from third_party import (X,
|
||||||
|
Y, Z)
|
||||||
|
# fmt: on
|
||||||
f"trigger 3.6 mode"
|
f"trigger 3.6 mode"
|
||||||
# fmt: off
|
# fmt: off
|
||||||
def func_no_args():
|
def func_no_args():
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
Just, Enough, Libraries, To, Fit, In, This, Nice, Split, Which, We, No, Longer, Use
|
Just, Enough, Libraries, To, Fit, In, This, Nice, Split, Which, We, No, Longer, Use
|
||||||
)
|
)
|
||||||
from name_of_a_company.extremely_long_project_name.component.ttypes import CuteLittleServiceHandlerFactoryyy
|
from name_of_a_company.extremely_long_project_name.component.ttypes import CuteLittleServiceHandlerFactoryyy
|
||||||
|
from name_of_a_company.extremely_long_project_name.extremely_long_component_name.ttypes import *
|
||||||
|
|
||||||
from .a.b.c.subprocess import *
|
from .a.b.c.subprocess import *
|
||||||
from . import (tasks)
|
from . import (tasks)
|
||||||
@ -87,6 +88,7 @@
|
|||||||
from name_of_a_company.extremely_long_project_name.component.ttypes import (
|
from name_of_a_company.extremely_long_project_name.component.ttypes import (
|
||||||
CuteLittleServiceHandlerFactoryyy
|
CuteLittleServiceHandlerFactoryyy
|
||||||
)
|
)
|
||||||
|
from name_of_a_company.extremely_long_project_name.extremely_long_component_name.ttypes import *
|
||||||
|
|
||||||
from .a.b.c.subprocess import *
|
from .a.b.c.subprocess import *
|
||||||
from . import tasks
|
from . import tasks
|
||||||
|
Loading…
Reference in New Issue
Block a user