This is a bug report.
from dataclasses import dataclass
from typing import Callable
@dataclass
class Repro:
fn: Callable[[int], str]
r = Repro(fn=repr)
assert "1" == r.fn(1)
Works correctly when dataclass is not used, i.e. when Repro is
class Repro:
def __init__(self, fn: Callable[[int], str]) -> None:
self.fn = fn
repro.py:9: error: Invalid self argument "Repro" to attribute function "fn" with type "Callable[[int], str]"
repro.py:9: error: Too many arguments
When running with Python, works correctly. Doesn't throw any exceptions.
Successful type check
Tested with two versions, 0.620 and current version from GitHub.
[mypy]
warn_redundant_casts = True
warn_unused_ignores = True
incremental = True
follow_imports = normal
ignore_missing_imports = True
disallow_untyped_calls = True
disallow_untyped_defs = True
check_untyped_defs = True
warn_return_any = True
warn_no_return = True
no_implicit_optional = True
strict_optional = True
This is not something specific to dataclasses. There is a simpler repro that gives same errors:
class Repro:
fn: Callable[[int], str]
r = Repro()
r.fn(1)
The problem is the same as in https://github.com/python/mypy/issues/708. I would however _not_ close this as a duplicate, because this issue highlights another aspect of the problem.
I just came across the same issue. I guess a lot of people are going to face this issue very soon, as it's very easy to reproduce it using dataclasses.
I guess this should be not hard to fix, mypy cares whether a callable was assigned in class (to match what Python does), so we should just tweak the Vars in plugin to pretend they were assigned on self. But we still need a volunteer who will fix this.
If someone needs a workaround, this works:
from dataclasses import dataclass
from typing import *
T = TypeVar("T")
@dataclass
class Box(Generic[T]):
inner: T
@property
def unboxed(self) -> T:
return self.inner
@dataclass
class Repro:
fn: Box[Callable[[int], str]]
Repro(fn=Box(repr)).fn.unboxed(1)
I've found that another workaround to this is to use a callback protocol instead of Callable
When using NamedTuple instead of dataclass this problem does not arise.
I volunteer to fix this and any guidances will be greatly helpful @ilevkivskyi
@TH3CHARLie Fixing this in general may be tricky, but fixing just the dataclass case, should be easy. In any case, please go ahead!
Most helpful comment
I've found that another workaround to this is to use a callback protocol instead of
Callable