Description
Hello,
I think I encountered a bug. But it's also possible I'm using default_factory
not correctly with type annotations.
The following code type-checked in mypy 0.630 but doesn't type-check anymore in mypy 0.641.
from typing import Any, Collection, List
from dataclasses import dataclass, field
class Foo:
pass
@dataclass
class A:
items: Collection[Foo] = field(default_factory=list) # error: Incompatible types
With mypy 0.641 I get the following error message:
error: Incompatible types in assignment (expression has type "List[_T]", variable has type "Collection[Foo]")
I want items
to be just a collection of Foo
instances so that it's ok instantiating it with a set
or a list
of Foo
items. It should work since both list
and set
are collections. I'm just using list
as a default factory since it is a simple default for a collection.
I can make it work if I'm using one of the following workarounds:
Workaround 1:
This type-checks but requires items
to be a list. So instantiating the dataclass like B([Foo(), Foo()])
works but B({Foo(), Foo()})
doesn't.
@dataclass
class B:
items: List[Foo] = field(default_factory=list) # ok
Workaround 2:
This type-checks as well but doesn't enforce items to be instances of Foo
anymore.
@dataclass
class C:
items: Collection[Any] = field(default_factory=list) # ok
Workaround 3:
This is the cleanest workaround but it is much more verbose than just default_factory=list
.
def make_foo_list() -> List[Foo]:
return []
@dataclass
class D:
items: Collection[Foo] = field(default_factory=make_foo_list) # ok
I am using Python 3.7.0 and mypy 0.641.
Other options I am using:
strict_optional = true
ignore_missing_imports = true
follow_imports = silent
warn_unused_ignores = true
warn_redundant_casts = true