@@ -157,14 +157,16 @@ def __str__(self):
157
157
INVALID_DEDENT = 5
158
158
159
159
160
- def lex (string : Union [str , bytes ], first_line : int = 1 , pyversion : int = 3 ) -> List [Token ]:
161
- """Analyze string and return an array of token objects.
160
+ def lex (string : Union [str , bytes ], first_line : int = 1 ,
161
+ pyversion : int = 3 ) -> Tuple [List [Token ], Set [int ]]:
162
+ """Analyze string, and return an array of token objects and the lines to ignore.
162
163
163
- The last token is always Eof.
164
+ The last token is always Eof. The intention is to ignore any
165
+ semantic and type check errors on the ignored lines.
164
166
"""
165
167
l = Lexer (pyversion )
166
168
l .lex (string , first_line )
167
- return l .tok
169
+ return l .tok , l . ignored_lines
168
170
169
171
170
172
# Reserved words (not including operators)
@@ -291,12 +293,16 @@ class Lexer:
291
293
292
294
pyversion = 3
293
295
296
+ # Lines to ignore (using # type: ignore).
297
+ ignored_lines = Undefined (Set [int ])
298
+
294
299
def __init__ (self , pyversion : int = 3 ) -> None :
295
300
self .map = [self .unknown_character ] * 256
296
301
self .tok = []
297
302
self .indents = [0 ]
298
303
self .open_brackets = []
299
304
self .pyversion = pyversion
305
+ self .ignored_lines = set ()
300
306
# Fill in the map from valid character codes to relevant lexer methods.
301
307
for seq , method in [('ABCDEFGHIJKLMNOPQRSTUVWXYZ' , self .lex_name ),
302
308
('abcdefghijklmnopqrstuvwxyz_' , self .lex_name ),
@@ -811,6 +817,8 @@ def add_pre_whitespace(self, s: str) -> None:
811
817
self .pre_whitespace += s
812
818
self .i += len (s )
813
819
820
+ type_ignore_exp = re .compile (r'[ \t]*#[ \t]*type:[ \t]*ignore\b' )
821
+
814
822
def add_token (self , tok : Token ) -> None :
815
823
"""Store a token.
816
824
@@ -823,6 +831,11 @@ def add_token(self, tok: Token) -> None:
823
831
and not isinstance (tok , Dedent )):
824
832
raise ValueError ('Empty token' )
825
833
tok .pre = self .pre_whitespace
834
+ if self .type_ignore_exp .match (tok .pre ):
835
+ delta = 0
836
+ if '\n ' in tok .pre or '\r ' in tok .pre :
837
+ delta += 1
838
+ self .ignored_lines .add (self .line - delta )
826
839
tok .line = self .line
827
840
self .tok .append (tok )
828
841
self .i += len (tok .string )
0 commit comments