Skip to content

Type check error with asdict  #987

Closed

Description

@dbertouille

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)

Activity

  1. hynek commented on Jul 29, 2022

    @hynek
    Member

    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.

  2. added
    TypingTyping/stub/Mypy/PyRight related bugs.
    on Jul 29, 2022
  3. 1oglop1 commented on Aug 5, 2022

    @1oglop1

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

  4. hynek commented on Aug 5, 2022

    @hynek
    Member

    @Tinche did we just forget it?

  5. Tinche commented on Aug 5, 2022

    @Tinche
    Member

    Yeah I think so ;/

  6. layday commented on Aug 8, 2022

    @layday
    Contributor

    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.

  7. hynek commented on Apr 3, 2023

    @hynek
    Member

    fixed by #997

  8. added a commit that references this issue on Mar 15, 2024
  9. added a commit that references this issue on Mar 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    TypingTyping/stub/Mypy/PyRight related bugs.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions