]> git.madduck.net Git - etc/vim.git/commitdiff

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:

Fix arithmetic stability issue (#2817)
authorShantanu <12621235+hauntsaninja@users.noreply.github.com>
Sat, 29 Jan 2022 00:57:05 +0000 (16:57 -0800)
committerGitHub <noreply@github.com>
Sat, 29 Jan 2022 00:57:05 +0000 (16:57 -0800)
It turns out "simple_stmt" isn't that simple: it can contain multiple
statements separated by semicolons. Invisible parenthesis logic for
arithmetic expressions only looked at the first child of simple_stmt.
This causes instability in the presence of semicolons, since the next
run through the statement following the semicolon will be the first
child of another simple_stmt.

I believe this along with #2572 fix the known stability issues.

CHANGES.md
src/black/linegen.py
src/black/nodes.py

index 274c5640ec018adb937502cea2e184dd38337f1d..b57a360f1bce3e6cc4263b35868b6f29f0c453d9 100644 (file)
@@ -24,6 +24,7 @@ and the first release covered by our new stability policy.
 - Don't add whitespace for attribute access on hexadecimal, binary, octal, and complex
   literals (#2799)
 - Treat blank lines in stubs the same inside top-level `if` statements (#2820)
+- Fix unstable formatting with semicolons and arithmetic expressions (#2817)
 
 ### Parser
 
index b572ed0b52fdbe6d546365ffbce2876466b568d0..495d3230f8fed640f421185fc962ec0714520e4d 100644 (file)
@@ -7,7 +7,7 @@ from typing import Collection, Iterator, List, Optional, Set, Union
 
 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 Visitor, syms, is_arith_like, ensure_visible
 from black.nodes import is_docstring, is_empty_tuple, is_one_tuple, is_one_tuple_between
 from black.nodes import is_name_token, is_lpar_token, is_rpar_token
 from black.nodes import is_walrus_assignment, is_yield, is_vararg, is_multiline_string
@@ -156,8 +156,12 @@ class LineGenerator(Visitor[Line]):
 
     def visit_simple_stmt(self, node: Node) -> Iterator[Line]:
         """Visit a statement without nested statements."""
-        if first_child_is_arith(node):
-            wrap_in_parentheses(node, node.children[0], visible=False)
+        prev_type: Optional[int] = None
+        for child in node.children:
+            if (prev_type is None or prev_type == token.SEMI) and is_arith_like(child):
+                wrap_in_parentheses(node, child, visible=False)
+            prev_type = child.type
+
         is_suite_like = node.parent and node.parent.type in STATEMENT
         if is_suite_like:
             if self.mode.is_pyi and is_stub_body(node):
index 51d4cb8618d0a6a2c1f8ac1d55318ed2579fb5d9..7466670be5a9864669790b0bd6948217441c435b 100644 (file)
@@ -531,15 +531,14 @@ def first_leaf_column(node: Node) -> Optional[int]:
     return None
 
 
-def first_child_is_arith(node: Node) -> bool:
-    """Whether first child is an arithmetic or a binary arithmetic expression"""
-    expr_types = {
+def is_arith_like(node: LN) -> bool:
+    """Whether node is an arithmetic or a binary arithmetic expression"""
+    return node.type in {
         syms.arith_expr,
         syms.shift_expr,
         syms.xor_expr,
         syms.and_expr,
     }
-    return bool(node.children and node.children[0].type in expr_types)
 
 
 def is_docstring(leaf: Leaf) -> bool: