@@ -575,6 +575,19 @@ def collect_attributes(self) -> list[DataclassAttribute] | None:
575575 # Second, collect attributes belonging to the current class.
576576 current_attr_names : set [str ] = set ()
577577 kw_only = self ._get_bool_arg ("kw_only" , self ._spec .kw_only_default )
578+ all_assignments = self ._get_assignment_statements_from_block (cls .defs )
579+ redefined_attrs : dict [str , list [AssignmentStmt ]] = {}
580+ last_def_with_type : dict [str , AssignmentStmt ] = {}
581+ for stmt in all_assignments :
582+ if not isinstance (stmt .lvalues [0 ], NameExpr ):
583+ continue
584+ name = stmt .lvalues [0 ].name
585+ if stmt .type is not None :
586+ last_def_with_type [name ] = stmt
587+ if name in redefined_attrs :
588+ redefined_attrs [name ].append (stmt )
589+ else :
590+ redefined_attrs [name ] = [stmt ]
578591 for stmt in self ._get_assignment_statements_from_block (cls .defs ):
579592 # Any assignment that doesn't use the new type declaration
580593 # syntax can be ignored out of hand.
@@ -608,7 +621,39 @@ def collect_attributes(self) -> list[DataclassAttribute] | None:
608621 # This might be a property / field name clash.
609622 # We will issue an error later.
610623 continue
624+ if not isinstance (node , Var ):
625+ if name in redefined_attrs and len (redefined_attrs [name ]) > 1 :
626+ continue
627+ self ._api .fail (
628+ f"Dataclass attribute '{ name } ' cannot be a function. "
629+ f"Use a variable with type annotation instead." ,
630+ stmt ,
631+ )
632+ continue
633+
634+ assert isinstance (node , Var ), node
611635
636+ if not isinstance (node , Var ):
637+ if name in redefined_attrs and len (redefined_attrs [name ]) > 1 :
638+ if name in last_def_with_type :
639+ continue
640+ last_def = redefined_attrs .get (name , [stmt ])[- 1 ]
641+ if last_def .type is not None :
642+ var = Var (name )
643+ var .is_property = False
644+ var .info = cls .info
645+ var .line = last_def .line
646+ var .column = last_def .column
647+ var .type = self ._api .anal_type (last_def .type )
648+ cls .info .names [name ] = SymbolTableNode (MDEF , var )
649+ node = var
650+ else :
651+ self ._api .fail (
652+ f"Dataclass attribute '{ name } ' cannot be a function. "
653+ f"Use a variable with type annotation instead." ,
654+ stmt ,
655+ )
656+ continue
612657 assert isinstance (node , Var ), node
613658
614659 # x: ClassVar[int] is ignored by dataclasses.
0 commit comments