@@ -176,18 +176,27 @@ def visit_call(self, node: nodes.Call) -> str:
176
176
args .extend (keywords )
177
177
return f"{ expr_str } ({ ', ' .join (args )} )"
178
178
179
+ def _handle_type_params (
180
+ self , type_params : list [nodes .TypeVar | nodes .ParamSpec | nodes .TypeVarTuple ]
181
+ ) -> str :
182
+ return (
183
+ f"[{ ', ' .join (tp .accept (self ) for tp in type_params )} ]"
184
+ if type_params
185
+ else ""
186
+ )
187
+
179
188
def visit_classdef (self , node : nodes .ClassDef ) -> str :
180
189
"""return an astroid.ClassDef node as string"""
181
190
decorate = node .decorators .accept (self ) if node .decorators else ""
191
+ type_params = self ._handle_type_params (node .type_params )
182
192
args = [n .accept (self ) for n in node .bases ]
183
193
if node ._metaclass and not node .has_metaclass_hack ():
184
194
args .append ("metaclass=" + node ._metaclass .accept (self ))
185
195
args += [n .accept (self ) for n in node .keywords ]
186
196
args_str = f"({ ', ' .join (args )} )" if args else ""
187
197
docs = self ._docs_dedent (node .doc_node )
188
- # TODO: handle type_params
189
- return "\n \n {}class {}{}:{}\n {}\n " .format (
190
- decorate , node .name , args_str , docs , self ._stmt_list (node .body )
198
+ return "\n \n {}class {}{}{}:{}\n {}\n " .format (
199
+ decorate , node .name , type_params , args_str , docs , self ._stmt_list (node .body )
191
200
)
192
201
193
202
def visit_compare (self , node : nodes .Compare ) -> str :
@@ -336,17 +345,18 @@ def visit_formattedvalue(self, node: nodes.FormattedValue) -> str:
336
345
def handle_functiondef (self , node : nodes .FunctionDef , keyword : str ) -> str :
337
346
"""return a (possibly async) function definition node as string"""
338
347
decorate = node .decorators .accept (self ) if node .decorators else ""
348
+ type_params = self ._handle_type_params (node .type_params )
339
349
docs = self ._docs_dedent (node .doc_node )
340
350
trailer = ":"
341
351
if node .returns :
342
352
return_annotation = " -> " + node .returns .as_string ()
343
353
trailer = return_annotation + ":"
344
- # TODO: handle type_params
345
- def_format = "\n %s%s %s(%s)%s%s\n %s"
354
+ def_format = "\n %s%s %s%s(%s)%s%s\n %s"
346
355
return def_format % (
347
356
decorate ,
348
357
keyword ,
349
358
node .name ,
359
+ type_params ,
350
360
node .args .accept (self ),
351
361
trailer ,
352
362
docs ,
@@ -455,7 +465,10 @@ def visit_nonlocal(self, node: nodes.Nonlocal) -> str:
455
465
456
466
def visit_paramspec (self , node : nodes .ParamSpec ) -> str :
457
467
"""return an astroid.ParamSpec node as string"""
458
- return node .name .accept (self )
468
+ default_value_str = (
469
+ f" = { node .default_value .accept (self )} " if node .default_value else ""
470
+ )
471
+ return f"**{ node .name .accept (self )} { default_value_str } "
459
472
460
473
def visit_pass (self , node : nodes .Pass ) -> str :
461
474
"""return an astroid.Pass node as string"""
@@ -545,15 +558,23 @@ def visit_tuple(self, node: nodes.Tuple) -> str:
545
558
546
559
def visit_typealias (self , node : nodes .TypeAlias ) -> str :
547
560
"""return an astroid.TypeAlias node as string"""
548
- return node .name .accept (self ) if node .name else "_"
561
+ type_params = self ._handle_type_params (node .type_params )
562
+ return f"type { node .name .accept (self )} { type_params } = { node .value .accept (self )} "
549
563
550
564
def visit_typevar (self , node : nodes .TypeVar ) -> str :
551
565
"""return an astroid.TypeVar node as string"""
552
- return node .name .accept (self ) if node .name else "_"
566
+ bound_str = f": { node .bound .accept (self )} " if node .bound else ""
567
+ default_value_str = (
568
+ f" = { node .default_value .accept (self )} " if node .default_value else ""
569
+ )
570
+ return f"{ node .name .accept (self )} { bound_str } { default_value_str } "
553
571
554
572
def visit_typevartuple (self , node : nodes .TypeVarTuple ) -> str :
555
573
"""return an astroid.TypeVarTuple node as string"""
556
- return "*" + node .name .accept (self ) if node .name else ""
574
+ default_value_str = (
575
+ f" = { node .default_value .accept (self )} " if node .default_value else ""
576
+ )
577
+ return f"*{ node .name .accept (self )} { default_value_str } "
557
578
558
579
def visit_unaryop (self , node : nodes .UnaryOp ) -> str :
559
580
"""return an astroid.UnaryOp node as string"""
0 commit comments