@@ -85,13 +85,17 @@ def infer_func_form(
8585 try :
8686 name , names = _find_func_form_arguments (node , context )
8787 try :
88- attributes = names .value .replace ("," , " " ).split ()
88+ attributes : list [ str ] = names .value .replace ("," , " " ).split ()
8989 except AttributeError as exc :
9090 # Handle attributes of NamedTuples
9191 if not enum :
92- attributes = [
93- _infer_first (const , context ).value for const in names .elts
94- ]
92+ attributes = []
93+ fields = _get_namedtuple_fields (node )
94+ if fields :
95+ fields_node = extract_node (fields )
96+ attributes = [
97+ _infer_first (const , context ).value for const in fields_node .elts
98+ ]
9599
96100 # Handle attributes of Enums
97101 else :
@@ -522,21 +526,31 @@ def infer_typing_namedtuple(
522526 if not isinstance (node .args [1 ], (nodes .List , nodes .Tuple )):
523527 raise UseInferenceDefault
524528
529+ return infer_named_tuple (node , context )
530+
531+
532+ def _get_namedtuple_fields (node : nodes .Call ) -> str :
533+ """Get and return fields of a NamedTuple in code-as-a-string.
534+
535+ Because the fields are represented in their code form we can
536+ extract a node from them later on.
537+ """
525538 names = []
526- for elt in node .args [1 ].elts :
539+ for elt in next (node .args [1 ].infer ()).elts :
540+ if isinstance (elt , nodes .Const ):
541+ names .append (elt .as_string ())
542+ continue
527543 if not isinstance (elt , (nodes .List , nodes .Tuple )):
528544 raise UseInferenceDefault
529545 if len (elt .elts ) != 2 :
530546 raise UseInferenceDefault
531547 names .append (elt .elts [0 ].as_string ())
532548
533- typename = node .args [0 ].as_string ()
534549 if names :
535550 field_names = f"({ ',' .join (names )} ,)"
536551 else :
537- field_names = "''"
538- node = extract_node (f"namedtuple({ typename } , { field_names } )" )
539- return infer_named_tuple (node , context )
552+ field_names = ""
553+ return field_names
540554
541555
542556def _is_enum_subclass (cls : astroid .ClassDef ) -> bool :
0 commit comments