Mypy: Wrong inference of dataclasses with custom __init__ and varargs.

Created on 14 Feb 2019  路  2Comments  路  Source: python/mypy

Small case to reproduce:

from typing import Tuple
from dataclasses import dataclass

@dataclass
class Foo:
    spams: Tuple[int, ...]

    def __init__(self, *spams: int) -> None:
        self.spams = spams

def build_foo(*spams: int) -> Foo:
    return Foo(*spams)

Checking that program with mypy 0.670 (Python 3.6), results in:

bug.py:13: error: Argument 1 to "Foo" has incompatible type "*Tuple[int, ...]"; expected "Tuple[int, ...]"

Without the @dataclass decorator the program passes. It seems that the dataclass is hiding the actual __init__.

bug priority-2-low topic-plugins

Most helpful comment

Hm, it looks like this behavior is unspecified. I just looked in the PEP, and it explicitly recommends using @dataclass(init=False) for custom __init__ methods, see https://www.python.org/dev/peps/pep-0557/#custom-init-method. My works correctly with init=False (i.e. doesn't auto-generate the __init__()).

On the other hand, mypy probably should follow the runtime behavior for such case. This is however very low priority, since mypy works correctly in the documented case.

All 2 comments

Hm, it looks like this behavior is unspecified. I just looked in the PEP, and it explicitly recommends using @dataclass(init=False) for custom __init__ methods, see https://www.python.org/dev/peps/pep-0557/#custom-init-method. My works correctly with init=False (i.e. doesn't auto-generate the __init__()).

On the other hand, mypy probably should follow the runtime behavior for such case. This is however very low priority, since mypy works correctly in the documented case.

I think that the python3.7 documentation defines the behavior:

init: If true (the default), a __init__() method will be generated.

If the class already defines __init__(), this parameter is ignored.

So if you have an __init__, then the dataclass is going to ignore the property that will instruct it to create an __init__ method (at least, that's how I read it).

Was this page helpful?
0 / 5 - 0 ratings