diff --git a/mypy/plugins/attrs.py b/mypy/plugins/attrs.py index b7b3821576ea..5ae7b72787a8 100644 --- a/mypy/plugins/attrs.py +++ b/mypy/plugins/attrs.py @@ -1022,7 +1022,7 @@ def add_method( ) -def _get_attrs_init_type(typ: Instance) -> CallableType | None: +def _get_attrs_init_type(typ: Instance) -> CallableType | None | AnyType: """ If `typ` refers to an attrs class, get the type of its initializer method. """ @@ -1030,9 +1030,16 @@ def _get_attrs_init_type(typ: Instance) -> CallableType | None: if magic_attr is None or not magic_attr.plugin_generated: return None init_method = typ.type.get_method("__init__") or typ.type.get_method(ATTRS_INIT_NAME) - if not isinstance(init_method, FuncDef) or not isinstance(init_method.type, CallableType): + if init_method is None: return None - return init_method.type + # case 1: normal FuncDef + if isinstance(init_method, FuncDef) and isinstance(init_method.type, CallableType): + return init_method.type + + # case 2: overloaded method + if isinstance(init_method, OverloadedFuncDef) and isinstance(init_method.type, Overloaded): + return AnyType(TypeOfAny.special_form) + return None def _fail_not_attrs_class(ctx: mypy.plugin.FunctionSigContext, t: Type, parent_t: Type) -> None: @@ -1086,6 +1093,8 @@ def _get_expanded_attr_types( if init_func is None: _fail_not_attrs_class(ctx, display_typ, parent_typ) return None + if isinstance(init_func, AnyType): + return None init_func = expand_type_by_instance(init_func, typ) # [1:] to skip the self argument of AttrClass.__init__ field_names = cast(list[str], init_func.arg_names[1:])