attrs icon indicating copy to clipboard operation
attrs copied to clipboard

Type check error with asdict

Open dbertouille opened this issue 3 years ago • 5 comments

Starting with version attrs 22.1.0, I started running into a type checking issue when running mypy. In particular, this occurs when calling asdict in parent class where that parent class does not use attrs but the child might.

This is a bit of an odd scenario so I'm not sure if the bug belongs here in attrs, mypy, or should just be an error. However, it did not produce any type checking errors using attrs 21.4.0.

import abc
import attr
from typing import Any, Dict


class BaseModel(abc.ABC):
    def to_dict(self) -> Dict[str, Any]:
        o = {}  # type: Dict[str, Any]
        if attr.has(type(self)):
            return attr.asdict(self)
        return vars(self).copy()


@attr.s(auto_attribs=True)
class Model(BaseModel):
    id: int = 0


model = Model(id=1)

if attr.has(type(model)):
    data = attr.asdict(model)

dbertouille avatar Jul 28 '22 20:07 dbertouille

Given that your asdict is protected by a has, I suspect that belongs into mypy because it's dynamic logic we can't express in attrs. But @Tinche might know more.

The problem is that we introduced an AttrsInstance Protocol. It looks like we forgot to add a newsfragment.

hynek avatar Jul 29 '22 04:07 hynek

@hynek I notice that AttrsInstance is not imported in attrs.__init__.pyi only defined in attr.__init__.pyi is that intentional?

1oglop1 avatar Aug 05 '22 06:08 1oglop1

@Tinche did we just forget it?

hynek avatar Aug 05 '22 06:08 hynek

Yeah I think so ;/

Tinche avatar Aug 05 '22 12:08 Tinche

Probably worth nothing that has is a perfect match for TypeGuard from Python 3.10 (or its backport from typing-extensions). In attrs/__init__.pyi:

def has(cls: type) -> TypeGuard[type[AttrsInstance]]: ...

Elsewhere:

[...]
        if attr.has(type(self)):
            # `self` is now an `AttrsInstance`
            return attr.asdict(self)  # Passes!

But I suspect that attrs would not want to depend on typing-extensions.

layday avatar Aug 08 '22 11:08 layday

fixed by #997

hynek avatar Apr 03 '23 08:04 hynek