Skip to content

Commit fa92556

Browse files
msullivansigmavirus24
authored andcommitted
In PEP 484 type comments, allow text after "# type: ignore" (#455)
* In PEP 484 type comments, allow text after "# type: ignore" This is to support allowing typecheckers to implement ignores for specific errors, using syntax like `# type: ignore=E1000` or `# type: ignore[type-mismatch` or some such. mypy is about to add support for ignoring specific errors following this design: python/mypy#7239 Support for extra text in type comments was implemented in CPython as https://bugs.python.org/issue36878 and in typed_ast as python/typed_ast#116. * add test back
1 parent cc2977f commit fa92556

File tree

3 files changed

+28
-5
lines changed

3 files changed

+28
-5
lines changed

pyflakes/checker.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,13 @@ def getAlternatives(n):
7676
FOR_TYPES = (ast.For,)
7777
LOOP_TYPES = (ast.While, ast.For)
7878

79-
# https://github.com/python/typed_ast/blob/55420396/ast27/Parser/tokenizer.c#L102-L104
79+
# https://github.com/python/typed_ast/blob/1.4.0/ast27/Parser/tokenizer.c#L102-L104
8080
TYPE_COMMENT_RE = re.compile(r'^#\s*type:\s*')
81-
# https://github.com/python/typed_ast/blob/55420396/ast27/Parser/tokenizer.c#L1400
82-
TYPE_IGNORE_RE = re.compile(TYPE_COMMENT_RE.pattern + r'ignore\s*(#|$)')
83-
# https://github.com/python/typed_ast/blob/55420396/ast27/Grammar/Grammar#L147
81+
# https://github.com/python/typed_ast/blob/1.4.0/ast27/Parser/tokenizer.c#L1408-L1413
82+
ASCII_NON_ALNUM = ''.join([chr(i) for i in range(128) if not chr(i).isalnum()])
83+
TYPE_IGNORE_RE = re.compile(
84+
TYPE_COMMENT_RE.pattern + r'ignore([{}]|$)'.format(ASCII_NON_ALNUM))
85+
# https://github.com/python/typed_ast/blob/1.4.0/ast27/Grammar/Grammar#L147
8486
TYPE_FUNC_RE = re.compile(r'^(\(.*?\))\s*->\s*(.*)$')
8587

8688

pyflakes/test/test_checker.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ def test_type_comment_without_whitespace(self):
154154

155155
def test_type_comment_starts_with_word_ignore(self):
156156
ret = self._collect('x = 1 # type: ignore[T]')
157-
self.assertSetEqual(ret, {(ast.Assign, ('# type: ignore[T]',))})
157+
self.assertSetEqual(ret, set())
158158

159159
def test_last_node_wins(self):
160160
"""

pyflakes/test/test_type_annotations.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,27 @@ def test_typeCommentsAssignedToPreviousNode(self):
343343
# type: F
344344
""")
345345

346+
def test_typeIgnore(self):
347+
self.flakes("""
348+
a = 0 # type: ignore
349+
b = 0 # type: ignore[excuse]
350+
c = 0 # type: ignore=excuse
351+
d = 0 # type: ignore [excuse]
352+
e = 0 # type: ignore whatever
353+
""")
354+
355+
def test_typeIgnoreBogus(self):
356+
self.flakes("""
357+
x = 1 # type: ignored
358+
""", m.UndefinedName)
359+
360+
def test_typeIgnoreBogusUnicode(self):
361+
error = (m.CommentAnnotationSyntaxError if version_info < (3,)
362+
else m.UndefinedName)
363+
self.flakes("""
364+
x = 2 # type: ignore\xc3
365+
""", error)
366+
346367
@skipIf(version_info < (3,), 'new in Python 3')
347368
def test_return_annotation_is_class_scope_variable(self):
348369
self.flakes("""

0 commit comments

Comments
 (0)