@@ -496,7 +496,7 @@ def guarded_eval(code: str, context: EvaluationContext):
496496 ast .Not : ("__not__" ,),
497497}
498498
499-
499+ GENERIC_CONTAINER_TYPES = ( dict , list , set , tuple , frozenset )
500500class ImpersonatingDuck :
501501 """A dummy class used to create objects of other classes without calling their ``__init__``"""
502502
@@ -658,6 +658,35 @@ def _handle_assign(node: ast.Assign, context: EvaluationContext):
658658 return None
659659
660660
661+ def _handle_annassign (node , context ):
662+ annotation_value = _resolve_annotation (eval_node (node .annotation , context ), context )
663+ value = node .value
664+
665+ # Use Value for generic types
666+ use_value = isinstance (annotation_value , GENERIC_CONTAINER_TYPES )
667+
668+ # LOCAL VARIABLE
669+ if getattr (node , "simple" , False ) and isinstance (node .target , ast .Name ):
670+ name = node .target .id
671+ if use_value :
672+ return _handle_assign (
673+ ast .Assign (targets = [node .target ], value = value ), context
674+ )
675+ context .transient_locals [name ] = annotation_value
676+ return None
677+
678+ # INSTANCE ATTRIBUTE
679+ if _is_instance_attribute_assignment (node .target , context ):
680+ attr = node .target .attr
681+ if use_value :
682+ return _handle_assign (
683+ ast .Assign (targets = [node .target ], value = value ), context
684+ )
685+ context .class_transients [attr ] = annotation_value
686+ return None
687+
688+ return None
689+
661690def _extract_args_and_kwargs (node : ast .Call , context : EvaluationContext ):
662691 args = [eval_node (arg , context ) for arg in node .args ]
663692 kwargs = {
@@ -900,42 +929,7 @@ def dummy_function(*args, **kwargs):
900929 if isinstance (node , ast .Assign ):
901930 return _handle_assign (node , context )
902931 if isinstance (node , ast .AnnAssign ):
903- if node .simple :
904- annotation_value = _resolve_annotation (
905- eval_node (node .annotation , context ), context
906- )
907- # If there's an actual value and annotation is generic, use value itself
908- if node .value is not None and type (annotation_value ) in (
909- dict ,
910- list ,
911- set ,
912- tuple ,
913- frozenset ,
914- ):
915- assign_node = ast .Assign (targets = [node .target ], value = node .value )
916- _handle_assign (assign_node , context )
917- else :
918- context .transient_locals [node .target .id ] = annotation_value
919-
920- # Handle non-simple annotated assignments only for self.x: type = value
921- if _is_instance_attribute_assignment (node .target , context ):
922- annotation_value = _resolve_annotation (
923- eval_node (node .annotation , context ), context
924- )
925-
926- if node .value is not None and annotation_value in (
927- dict ,
928- list ,
929- set ,
930- tuple ,
931- frozenset ,
932- ):
933- assign_node = ast .Assign (targets = [node .target ], value = node .value )
934- _handle_assign (assign_node , context )
935- else :
936- context .class_transients [node .target .attr ] = annotation_value
937-
938- return None
932+ return _handle_annassign (node , context )
939933 if isinstance (node , ast .Expression ):
940934 return eval_node (node .body , context )
941935 if isinstance (node , ast .Expr ):
0 commit comments