Skip to content

Commit d8320ec

Browse files
msullivanilevkivskyi
authored andcommitted
bpo-36878: Allow extra text after # type: ignore comments (GH-13238)
In the parser, when using the type_comments=True option, recognize a TYPE_IGNORE as anything containing `# type: ignore` followed by a non-alphanumeric character. This is to allow ignores such as `# type: ignore[E1000]`.
1 parent 6236c98 commit d8320ec

File tree

3 files changed

+17
-9
lines changed

3 files changed

+17
-9
lines changed

Lib/test/test_type_comments.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,12 @@ def foo():
7676
7777
def bar():
7878
x = 1 # type: ignore
79+
80+
def baz():
81+
pass # type: ignore[excuse]
82+
pass # type: ignore=excuse
83+
pass # type: ignore [excuse]
84+
x = 1 # type: ignore whatever
7985
"""
8086

8187
# Test for long-form type-comments in arguments. A test function
@@ -266,7 +272,7 @@ def test_vardecl(self):
266272

267273
def test_ignores(self):
268274
for tree in self.parse_all(ignores):
269-
self.assertEqual([ti.lineno for ti in tree.type_ignores], [2, 5])
275+
self.assertEqual([ti.lineno for ti in tree.type_ignores], [2, 5, 8, 9, 10, 11])
270276
tree = self.classic_parse(ignores)
271277
self.assertEqual(tree.type_ignores, [])
272278

@@ -318,6 +324,7 @@ def check_both_ways(source):
318324
check_both_ways("while True:\n continue # type: int\n")
319325
check_both_ways("try: # type: int\n pass\nfinally:\n pass\n")
320326
check_both_ways("try:\n pass\nfinally: # type: int\n pass\n")
327+
check_both_ways("pass # type: ignorewhatever\n")
321328

322329
def test_func_type_input(self):
323330

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
When using `type_comments=True` in `ast.parse`, treat `# type: ignore` followed by
2+
a non-alphanumeric character and then arbitrary text as a type ignore, instead of
3+
requiring nothing but whitespace or another comment. This is to permit formations
4+
such as `# type: ignore[E1000]`.

Parser/tokenizer.c

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,14 +1272,11 @@ tok_get(struct tok_state *tok, char **p_start, char **p_end)
12721272

12731273
type_start = p;
12741274

1275-
is_type_ignore = tok->cur >= p + 6 && memcmp(p, "ignore", 6) == 0;
1276-
p += 6;
1277-
while (is_type_ignore && p < tok->cur) {
1278-
if (*p == '#')
1279-
break;
1280-
is_type_ignore = is_type_ignore && (*p == ' ' || *p == '\t');
1281-
p++;
1282-
}
1275+
/* A TYPE_IGNORE is "type: ignore" followed by the end of the token
1276+
* or anything non-alphanumeric. */
1277+
is_type_ignore = (
1278+
tok->cur >= p + 6 && memcmp(p, "ignore", 6) == 0
1279+
&& !(tok->cur > p + 6 && isalnum(p[6])));
12831280

12841281
if (is_type_ignore) {
12851282
/* If this type ignore is the only thing on the line, consume the newline also. */

0 commit comments

Comments
 (0)