Closed
Labels
false-positivemypy gave an error on correct codemypy gave an error on correct codegood-first-issuepriority-1-normal
Description
Minimum repro:
object(*[])
object(**{})This gives the following errors:
Too many arguments for "object"
Too many arguments for "object"
I think this is valid code and should pass the type check.
Context: I encountered this when I tried to write a multiple inheritance model where each class is passing arguments to the next parent (in terms of MRO):
class A(object):
def __init__(self, a_arg: int, **kwds: Any) -> None:
super().__init__(**kwds)
class B(object):
def __init__(self, b_arg: int, **kwds: Any) -> None:
super().__init__(**kwds)
class C(A, B):
def __init__(self, c_arg: int, **kwds: Any) -> None:
super().__init__(**kwds)
C(a_arg=1, b_arg=2, c_arg=3)
# This code runs fine but gives three type errors saying:
# Too many arguments for "__init__" of "object"You cannot expect a static derivation order due to the dynamic nature of MRO, so it's hard to avoid this error from happening.
Reacted by Max Kühn, Neil Girdhar, Kevin L., Daniel Hahler, Miroslav Štola, lemon24, feliam, otakart and Ali
Metadata
Metadata
Assignees
Labels
false-positivemypy gave an error on correct codemypy gave an error on correct codegood-first-issuepriority-1-normal
Activity
gvanrossum commentedon Sep 25, 2017
While your minimal repro indeed gives those errors (and probably shouldn't), in your actual example things are not so simple -- mypy only looks at your source code, it doesn't execute your code, so when it type-checks the line
super().__init__(**kwds)in your full example it can't actually assume that the argument list forobject()is empty -- this depends on the call site, and while you show a call that would indeed result in an empty argument list, there may be other calls toC()that end up passing a non-emptykwdstoobject(). Mypy type-checks calls purely on the basis of the given signature, and the signature forC()says that any keyword arguments are accepted.astrojuanlu commentedon Feb 8, 2018
Is this related to #4335?
gvanrossum commentedon Feb 9, 2018
@Juanlu001
I don't see how. Maybe you mistyped the issue number? #4335 is about multiple inheritance. This issue is about varargs function calls.
astrojuanlu commentedon Feb 9, 2018
I was confused because the original example in this issue used multiple inheritance as well.
ilevkivskyi commentedon Sep 27, 2019
The first example
object(*[])now works correctly, second one still fails. Should be probably not hard to fix.momohatt commentedon Mar 22, 2020
Hi, I'd like to work on this as my first issue and I have a question.
Current implementation requires the type of
kwargsin**kwargsto be a subtype ofdict[str, <any>].mypy/mypy/checkexpr.py
Lines 3790 to 3795 in 1677efd
However, an empty dictionary
{}is currently typed asdict[<nothing>, <nothing>]and fails this check, presumably because dictionary types are contravariant at the key position. Would it be better to type{}asdict[<any>, <nothing>]?EDIT: I think #5580 is the same problem as this
NeilGirdhar commentedon May 4, 2020
This issue is explained with
__init__, but the same problem happens when calling super in other methods like__init_subclass__.momohatt commentedon Oct 22, 2020
I think it's difficult to judge whether a given dictionary is empty or not, so we cannot help but give up the "Too many arguments" check whenever there are arguments like
**kwds(i.e. the third line of the following should not raise error)This is consistent with the case of lists and variable-length tuples:
At first I thought we can take advantage of the fact that an empty dictionary is typed as
dict[<nothing>, <nothing>], but that will contradict with this solution (#5580 (comment)) on fixing the incorrect type checking on**arguments...Fix argument checking on empty dict with double stars (#9629)