Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Dataclasses: default_factory=list doesn't work for Collection[Foo] #5823

Closed
phwh opened this issue Oct 23, 2018 · 1 comment
Closed

Dataclasses: default_factory=list doesn't work for Collection[Foo] #5823

phwh opened this issue Oct 23, 2018 · 1 comment

Comments

@phwh
Copy link

phwh commented Oct 23, 2018

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
@ilevkivskyi
Copy link
Member

This is a duplicate of #5738 (already high priority, since this is a regression). We are discussing possible solutions, hopefully this will be fixed in the next release.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants