@@ -648,6 +648,7 @@ def __init__(self):
648648 self ._source = []
649649 self ._buffer = []
650650 self ._precedences = {}
651+ self ._type_ignores = {}
651652 self ._indent = 0
652653
653654 def interleave (self , inter , f , seq ):
@@ -697,11 +698,15 @@ def buffer(self):
697698 return value
698699
699700 @contextmanager
700- def block (self ):
701+ def block (self , * , extra = None ):
701702 """A context manager for preparing the source for blocks. It adds
702703 the character':', increases the indentation on enter and decreases
703- the indentation on exit."""
704+ the indentation on exit. If *extra* is given, it will be directly
705+ appended after the colon character.
706+ """
704707 self .write (":" )
708+ if extra :
709+ self .write (extra )
705710 self ._indent += 1
706711 yield
707712 self ._indent -= 1
@@ -748,6 +753,11 @@ def get_raw_docstring(self, node):
748753 if isinstance (node , Constant ) and isinstance (node .value , str ):
749754 return node
750755
756+ def get_type_comment (self , node ):
757+ comment = self ._type_ignores .get (node .lineno ) or node .type_comment
758+ if comment is not None :
759+ return f" # type: { comment } "
760+
751761 def traverse (self , node ):
752762 if isinstance (node , list ):
753763 for item in node :
@@ -770,7 +780,12 @@ def _write_docstring_and_traverse_body(self, node):
770780 self .traverse (node .body )
771781
772782 def visit_Module (self , node ):
783+ self ._type_ignores = {
784+ ignore .lineno : f"ignore{ ignore .tag } "
785+ for ignore in node .type_ignores
786+ }
773787 self ._write_docstring_and_traverse_body (node )
788+ self ._type_ignores .clear ()
774789
775790 def visit_FunctionType (self , node ):
776791 with self .delimit ("(" , ")" ):
@@ -811,6 +826,8 @@ def visit_Assign(self, node):
811826 self .traverse (target )
812827 self .write (" = " )
813828 self .traverse (node .value )
829+ if type_comment := self .get_type_comment (node ):
830+ self .write (type_comment )
814831
815832 def visit_AugAssign (self , node ):
816833 self .fill ()
@@ -966,7 +983,7 @@ def _function_helper(self, node, fill_suffix):
966983 if node .returns :
967984 self .write (" -> " )
968985 self .traverse (node .returns )
969- with self .block ():
986+ with self .block (extra = self . get_type_comment ( node ) ):
970987 self ._write_docstring_and_traverse_body (node )
971988
972989 def visit_For (self , node ):
@@ -980,7 +997,7 @@ def _for_helper(self, fill, node):
980997 self .traverse (node .target )
981998 self .write (" in " )
982999 self .traverse (node .iter )
983- with self .block ():
1000+ with self .block (extra = self . get_type_comment ( node ) ):
9841001 self .traverse (node .body )
9851002 if node .orelse :
9861003 self .fill ("else" )
@@ -1018,13 +1035,13 @@ def visit_While(self, node):
10181035 def visit_With (self , node ):
10191036 self .fill ("with " )
10201037 self .interleave (lambda : self .write (", " ), self .traverse , node .items )
1021- with self .block ():
1038+ with self .block (extra = self . get_type_comment ( node ) ):
10221039 self .traverse (node .body )
10231040
10241041 def visit_AsyncWith (self , node ):
10251042 self .fill ("async with " )
10261043 self .interleave (lambda : self .write (", " ), self .traverse , node .items )
1027- with self .block ():
1044+ with self .block (extra = self . get_type_comment ( node ) ):
10281045 self .traverse (node .body )
10291046
10301047 def visit_JoinedStr (self , node ):
0 commit comments