Skip to content

Overloaded __init__ prevents type from being recognized as an attrs class #19003

Open
@samueljsb

Description

@samueljsb

Bug Report

When an attrs class has and overloaded __init__ function, mypy does not consider it to be an attrs class when evaluating attrs.evolve.

To Reproduce

from typing import overload

import attrs


@attrs.frozen(init=False)
class C:
    x: int | str

    @overload
    def __init__(self, x: int) -> None: ...

    @overload
    def __init__(self, x: str) -> None: ...

    def __init__(self, x: int | str) -> None:
        self.__attrs_init__(x)


obj = C(1)
attrs.evolve(obj, x=2)  # error

Expected Behavior

The C instance should be an acceptable input to attrs.evolve.

Actual Behavior

$ mypy t.py
t.py:21: error: Argument 1 to "evolve" has incompatible type "C"; expected an attrs class  [misc]
Found 1 error in 1 file (checked 1 source file)

Your Environment

  • Mypy version used: mypy 1.15.0
  • Mypy command-line flags: none
  • Mypy configuration options from mypy.ini (and other config files): none
  • Python version used: Python 3.13.0 (v3.13.0:60403a5409f, Oct 7 2024, 00:37:40) [Clang 15.0.0 (clang-1500.3.9.4)]

Notes

This appears to be because the init method is both not a FuncDef (it is OverloadedFuncDef) and its type attribute is not a CallableType. See:

mypy/mypy/plugins/attrs.py

Lines 1033 to 1034 in 7b4f631

if not isinstance(init_method, FuncDef) or not isinstance(init_method.type, CallableType):
return None

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions