]> 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 a magical comment caused internal error (#3740)
authorrdrll <13176405+rdrll@users.noreply.github.com>
Tue, 27 Jun 2023 14:23:39 +0000 (07:23 -0700)
committerGitHub <noreply@github.com>
Tue, 27 Jun 2023 14:23:39 +0000 (07:23 -0700)
`is_type_comment` now specifically deals with general type comments for a leaf.
`is_type_ignore_comment` now handles type comments contains ignore annotation for a leaf
`is_type_ignore_comment_string` used to determine if a string is an ignore type comment

CHANGES.md
src/black/linegen.py
src/black/lines.py
src/black/nodes.py
tests/data/simple_cases/multiline_consecutive_open_parentheses_ignore.py [new file with mode: 0644]

index 6fa0e4b7cc0d8e0299538a055b7098ef6e0779f6..2dfed8a0dc4bc76d7c664c1250c6aa3e7ed03cad 100644 (file)
@@ -12,6 +12,8 @@
 
 - Fix a bug where an illegal trailing comma was added to return type annotations using
   PEP 604 unions (#3735)
 
 - Fix a bug where an illegal trailing comma was added to return type annotations using
   PEP 604 unions (#3735)
+- Fix a bug where multi-line open parenthesis magic comment like `type: ignore` were not
+  correctly parsed (#3740)
 
 ### Preview style
 
 
 ### Preview style
 
index ad21307c311b83b0e0eb964b34ae6149cfcb0cee..5ef3bbd170578159249eb9f850676767a9bc1f56 100644 (file)
@@ -49,6 +49,7 @@ from black.nodes import (
     is_stub_body,
     is_stub_suite,
     is_tuple_containing_walrus,
     is_stub_body,
     is_stub_suite,
     is_tuple_containing_walrus,
+    is_type_ignore_comment_string,
     is_vararg,
     is_walrus_assignment,
     is_yield,
     is_vararg,
     is_walrus_assignment,
     is_yield,
@@ -1399,8 +1400,13 @@ def maybe_make_parens_invisible_in_atom(
     if is_lpar_token(first) and is_rpar_token(last):
         middle = node.children[1]
         # make parentheses invisible
     if is_lpar_token(first) and is_rpar_token(last):
         middle = node.children[1]
         # make parentheses invisible
-        first.value = ""
-        last.value = ""
+        if (
+            # If the prefix of `middle` includes a type comment with
+            # ignore annotation, then we do not remove the parentheses
+            not is_type_ignore_comment_string(middle.prefix.strip())
+        ):
+            first.value = ""
+            last.value = ""
         maybe_make_parens_invisible_in_atom(
             middle,
             parent=parent,
         maybe_make_parens_invisible_in_atom(
             middle,
             parent=parent,
index daf0444d24e9a7d57c86f290344323fc7397f775..ea8fe520756d3a61702cf9e81453416bf534b632 100644 (file)
@@ -28,6 +28,7 @@ from black.nodes import (
     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,
@@ -251,7 +252,7 @@ class Line:
             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
@@ -288,7 +289,7 @@ class Line:
             # 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):
                         return True
 
         return False
                         return True
 
         return False
index 45070909df466c2fce7746788e6ac762c5a091a7..b019b0c64404f1912bf9fcbe70a9ab5c99c1c2a9 100644 (file)
@@ -816,12 +816,27 @@ def is_async_stmt_or_funcdef(leaf: Leaf) -> bool:
     )
 
 
     )
 
 
-def is_type_comment(leaf: Leaf, suffix: str = "") -> bool:
-    """Return True if the given leaf is a special comment.
-    Only returns true for type comments for now."""
+def is_type_comment(leaf: Leaf) -> bool:
+    """Return True if the given leaf is a type comment. This function should only
+    be used for general type comments (excluding ignore annotations, which should
+    use `is_type_ignore_comment`). Note that general type comments are no longer
+    used in modern version of Python, this function may be deprecated in the future."""
     t = leaf.type
     v = leaf.value
     t = leaf.type
     v = leaf.value
-    return t in {token.COMMENT, STANDALONE_COMMENT} and v.startswith("# type:" + suffix)
+    return t in {token.COMMENT, STANDALONE_COMMENT} and v.startswith("# type:")
+
+
+def is_type_ignore_comment(leaf: Leaf) -> bool:
+    """Return True if the given leaf is a type comment with ignore annotation."""
+    t = leaf.type
+    v = leaf.value
+    return t in {token.COMMENT, STANDALONE_COMMENT} and is_type_ignore_comment_string(v)
+
+
+def is_type_ignore_comment_string(value: str) -> bool:
+    """Return True if the given string match with type comment with
+    ignore annotation."""
+    return value.startswith("# type: ignore")
 
 
 def wrap_in_parentheses(parent: Node, child: LN, *, visible: bool = True) -> None:
 
 
 def wrap_in_parentheses(parent: Node, child: LN, *, visible: bool = True) -> None:
diff --git a/tests/data/simple_cases/multiline_consecutive_open_parentheses_ignore.py b/tests/data/simple_cases/multiline_consecutive_open_parentheses_ignore.py
new file mode 100644 (file)
index 0000000..6ec8bb4
--- /dev/null
@@ -0,0 +1,41 @@
+# This is a regression test. Issue #3737
+
+a = (  # type: ignore
+    int(  # type: ignore
+        int(  # type: ignore
+            int(  # type: ignore
+                6
+            )
+        )
+    )
+)
+
+b = (
+    int(
+        6
+    )
+)
+
+print(   "111") # type: ignore
+print(   "111"                         ) # type: ignore
+print(   "111"       ) # type: ignore
+
+
+# output
+
+
+# This is a regression test. Issue #3737
+
+a = (  # type: ignore
+    int(  # type: ignore
+        int(  # type: ignore
+            int(6)  # type: ignore
+        )
+    )
+)
+
+b = int(6)
+
+print("111")  # type: ignore
+print("111")  # type: ignore
+print("111")  # type: ignore
\ No newline at end of file