`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
- 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
is_stub_body,
is_stub_suite,
is_tuple_containing_walrus,
+ is_type_ignore_comment_string,
is_vararg,
is_walrus_assignment,
is_yield,
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,
is_multiline_string,
is_one_sequence_between,
is_type_comment,
+ is_type_ignore_comment,
is_with_or_async_with_stmt,
replace_child,
syms,
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
# 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
)
-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
- 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:
--- /dev/null
+# 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