Skip to content
New issue

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

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

Already on GitHub? Sign in 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.

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

No branches or pull requests

2 participants