Skip to content

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

Closed
@phwh

Description

@phwh

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions