22import sys
33
44from typing import (
5- Tuple , Union , TypeVar , Callable , Sequence , Optional , Any , Dict , cast , List , overload
5+ Tuple , Union , TypeVar , Callable , Sequence , Optional , Any , Dict , cast , List , overload , Set
66)
77MYPY = False
88if MYPY :
@@ -258,7 +258,7 @@ def __init__(self,
258258 self .is_stub = is_stub
259259 self .errors = errors
260260
261- self .extra_type_ignores = [] # type: List [int]
261+ self .type_ignores = set () # type: Set [int]
262262
263263 # Cache of visit_X methods keyed by type of visited object
264264 self .visitor_cache = {} # type: Dict[type, Callable[[Optional[AST]], Any]]
@@ -294,11 +294,29 @@ def translate_expr_list(self, l: Sequence[AST]) -> List[Expression]:
294294 res .append (exp )
295295 return res
296296
297- def translate_stmt_list (self , l : Sequence [AST ]) -> List [Statement ]:
297+ def get_lineno (self , node : Union [ast3 .expr , ast3 .stmt ]) -> int :
298+ if (isinstance (node , (ast3 .AsyncFunctionDef , ast3 .ClassDef , ast3 .FunctionDef ))
299+ and node .decorator_list ):
300+ return node .decorator_list [0 ].lineno
301+ return node .lineno
302+
303+ def translate_stmt_list (self ,
304+ stmts : Sequence [ast3 .stmt ],
305+ ismodule : bool = False ) -> List [Statement ]:
306+ # A "# type: ignore" comment before the first statement of a module
307+ # ignores the whole module:
308+ if (ismodule and stmts and self .type_ignores
309+ and min (self .type_ignores ) < self .get_lineno (stmts [0 ])):
310+ self .errors .used_ignored_lines [self .errors .file ].add (min (self .type_ignores ))
311+ block = Block (self .fix_function_overloads (self .translate_stmt_list (stmts )))
312+ block .is_unreachable = True
313+ return [block ]
314+
298315 res = [] # type: List[Statement]
299- for e in l :
300- stmt = self .visit (e )
301- res .append (stmt )
316+ for stmt in stmts :
317+ node = self .visit (stmt )
318+ res .append (node )
319+
302320 return res
303321
304322 op_map = {
@@ -403,13 +421,12 @@ def translate_module_id(self, id: str) -> str:
403421 return id
404422
405423 def visit_Module (self , mod : ast3 .Module ) -> MypyFile :
406- body = self .fix_function_overloads (self .translate_stmt_list (mod .body ))
407- ignores = [ti .lineno for ti in mod .type_ignores ]
408- ignores .extend (self .extra_type_ignores )
424+ self .type_ignores = {ti .lineno for ti in mod .type_ignores }
425+ body = self .fix_function_overloads (self .translate_stmt_list (mod .body , ismodule = True ))
409426 return MypyFile (body ,
410427 self .imports ,
411428 False ,
412- set ( ignores ) ,
429+ self . type_ignores ,
413430 )
414431
415432 # --- stmt ---
@@ -615,7 +632,7 @@ def make_argument(self, arg: ast3.arg, default: Optional[ast3.expr], kind: int,
615632 elif type_comment is not None :
616633 extra_ignore , arg_type = parse_type_comment (type_comment , arg .lineno , self .errors )
617634 if extra_ignore :
618- self .extra_type_ignores . append (arg .lineno )
635+ self .type_ignores . add (arg .lineno )
619636
620637 return Argument (Var (arg .arg ), arg_type , self .visit (default ), kind )
621638
@@ -673,7 +690,7 @@ def visit_Assign(self, n: ast3.Assign) -> AssignmentStmt:
673690 if n .type_comment is not None :
674691 extra_ignore , typ = parse_type_comment (n .type_comment , n .lineno , self .errors )
675692 if extra_ignore :
676- self .extra_type_ignores . append (n .lineno )
693+ self .type_ignores . add (n .lineno )
677694 else :
678695 typ = None
679696 s = AssignmentStmt (lvalues , rvalue , type = typ , new_syntax = False )
@@ -707,7 +724,7 @@ def visit_For(self, n: ast3.For) -> ForStmt:
707724 if n .type_comment is not None :
708725 extra_ignore , target_type = parse_type_comment (n .type_comment , n .lineno , self .errors )
709726 if extra_ignore :
710- self .extra_type_ignores . append (n .lineno )
727+ self .type_ignores . add (n .lineno )
711728 else :
712729 target_type = None
713730 node = ForStmt (self .visit (n .target ),
@@ -722,7 +739,7 @@ def visit_AsyncFor(self, n: ast3.AsyncFor) -> ForStmt:
722739 if n .type_comment is not None :
723740 extra_ignore , target_type = parse_type_comment (n .type_comment , n .lineno , self .errors )
724741 if extra_ignore :
725- self .extra_type_ignores . append (n .lineno )
742+ self .type_ignores . add (n .lineno )
726743 else :
727744 target_type = None
728745 node = ForStmt (self .visit (n .target ),
@@ -753,7 +770,7 @@ def visit_With(self, n: ast3.With) -> WithStmt:
753770 if n .type_comment is not None :
754771 extra_ignore , target_type = parse_type_comment (n .type_comment , n .lineno , self .errors )
755772 if extra_ignore :
756- self .extra_type_ignores . append (n .lineno )
773+ self .type_ignores . add (n .lineno )
757774 else :
758775 target_type = None
759776 node = WithStmt ([self .visit (i .context_expr ) for i in n .items ],
@@ -767,7 +784,7 @@ def visit_AsyncWith(self, n: ast3.AsyncWith) -> WithStmt:
767784 if n .type_comment is not None :
768785 extra_ignore , target_type = parse_type_comment (n .type_comment , n .lineno , self .errors )
769786 if extra_ignore :
770- self .extra_type_ignores . append (n .lineno )
787+ self .type_ignores . add (n .lineno )
771788 else :
772789 target_type = None
773790 s = WithStmt ([self .visit (i .context_expr ) for i in n .items ],
0 commit comments