3

I have a TypedDict DictWithOnlyX inside an attrs data class Example where mypy complains about the type returned from the getdict() method of my class, even though the return type is declared:

from typing_extensions import TypedDict
from attr import attrs, attrib, Factory, fields

DictWithOnlyX = TypedDict('DictWithOnlyX', {"x": str})

@attrs
class Example(object):
    name: str = attrib(default="")
    dx = attrib(factory=DictWithOnlyX)

    def getdict(self) -> DictWithOnlyX:
        return self.dx  # <-- mypy compains

mypy complains error: Incompatible return value type (got "DictWithOnlyX", expected "DictWithOnlyX")

The irony is, when solve the mypy problem by declaring the type of the attrib() I get another mypy error - whack a mole!

@attrs
class Example(object):
    name: str = attrib(default="")
    dx: DictWithOnlyX = attrib(factory=DictWithOnlyX)  # <-- mypy compains

    def getdict(self) -> DictWithOnlyX:
        return self.dx

mypy complains error: Incompatible types in assignment (expression has type "DictWithOnlyX", variable has type "DictWithOnlyX")

Both versions of the above code run OK. Python 3.7.5.

Both error messages are mysterious because they seem self contradictory - how can types that are (reported to be) the same be 'Incompatible'?

loki
  • 976
  • 1
  • 10
  • 22
abulka
  • 1,316
  • 13
  • 18

1 Answers1

0

That looks like a mypy bug to me. But I'm surprised it works that well at all, since you're side-stepping attrs' typing support completely! The idiomatic way to define the class would be

@attrs(auto_attribs=True)
class Example(object):
    name: str = ""
    dx: DictWithOnlyX = Factory(DictWithOnlyX)

But that causes the same error message.

hynek
  • 3,647
  • 1
  • 18
  • 26