Skip to content

No overload variant of "fromkeys" of "dict" matches argument types [typing.Iterable[Any], Union[Any, def (*Any, **Any) -> Any]] #2254

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

Closed
trnsnt opened this issue Oct 14, 2016 · 10 comments
Labels
bug mypy got something wrong false-positive mypy gave an error on correct code priority-1-normal

Comments

@trnsnt
Copy link

trnsnt commented Oct 14, 2016

Hello,

I have defined a dict wrapper where I override fromkeys method.
I have this method signature

    def fromkeys(cls, iterable, value=None):
        # type: (Iterable, Union[Any, Callable]) -> DictWrapper

and this give me the following error : No overload variant of "fromkeys" of "dict" matches argument types [typing.Iterable[Any], Union[Any, def (_Any, *_Any) -> Any]]

Thanks !

@gvanrossum
Copy link
Member

Thanks for the question! I'd be happy to help but I'm not sure I understand the context of that definition. Can you show a complete, small, self-contained program that exhibits this behavior?

@trnsnt
Copy link
Author

trnsnt commented Oct 14, 2016

Hello, thanks for the reply. Here is what I have done.
I have this class

class DictWrapper(dict):

    @classmethod
    def fromkeys(cls, iterable, value=None):
        # type: (Iterable, Union[Any, Callable]) -> DictWrapper
        if not callable(value):
            return DictWrapper(super(d, cls).fromkeys(iterable, value))

        def _():
            for key in iterable:
                yield key, value(key)

        return DictWrapper(_())

Code is working fine (Python 3.5), but when I run mypy, I have the following error :

No overload variant of "fromkeys" of "dict" matches argument types [typing.Iterable[Any], Union[Any, def (Any, *Any) -> Any]]

I am not sure if it is a problem, or if I have done something wrong.

@gvanrossum
Copy link
Member

Oh, it seems you've hit two issues! When I run that example I get:

__tmp__.py: note: In class "DictWrapper":
__tmp__.py:6: error: Signature of "fromkeys" incompatible with supertype "dict"
__tmp__.py: note: In member "fromkeys" of class "DictWrapper":
__tmp__.py:9: error: No overload variant of "fromkeys" of "dict" matches argument types [typing.Iterable[Any], Union[Any, def (*Any, **Any) -> Any]]

(Line 6 is the def, line 9 is the super() call.)

The first complaint is because in typeshed, fromkeys() is defined as a static method, while it is actually a class method. I don't know why this is, but I think I can just fix that.

The second complaint is probably because mypy doesn't understand callable(value) and hence it doesn't believe that the value you pass to the superclass version of fromkeys() matches the required type. This is issue #1973.

My recommendation is to add a # type: ignore to the offending line and proceed.

gvanrossum pushed a commit to python/typeshed that referenced this issue Oct 14, 2016
This came up in python/mypy#2254.

I don't know why it was previously defined as a staticmethod, perhaps
there was an old mypy issue?
@rwbarton
Copy link
Contributor

Isn't the second error just because you passed an Iterable, but dict.fromkeys expects a Sequence?

gvanrossum added a commit to python/typeshed that referenced this issue Oct 14, 2016
This came up in python/mypy#2254.

I don't know why it was previously defined as a staticmethod, perhaps
there was an old mypy issue?
@gvanrossum
Copy link
Member

Oh, good catch! I will fix that at the same time. Wait for the next iteration of python/typeshed#604.

@gvanrossum
Copy link
Member

OK then I think I have fixed both issues and this can be closed. @trnsnt, to get the fix right away you'll have to pull down the mypy repo, git submodule update, and then in the typeshed subdir do something like "git co master; git pull".

@gvanrossum
Copy link
Member

Sadly making fromkeys() a classmethod breaks, due to #328, so this is not fixed. Really sorry!! I went too fast here.

@gvanrossum gvanrossum reopened this Oct 15, 2016
@gvanrossum
Copy link
Member

(And this is not a duplicate of that issue -- there's the separate problem that Reid pointed out about the real fromkeys() taking an Iterable.)

@gvanrossum gvanrossum added bug mypy got something wrong and removed question labels Oct 15, 2016
@gvanrossum
Copy link
Member

Keeping this open until #328 is fixed and typeshed has been updated.

@gvanrossum gvanrossum added this to the 0.5 milestone Oct 27, 2016
@gvanrossum gvanrossum removed this from the 0.5 milestone Mar 29, 2017
@JukkaL JukkaL added the false-positive mypy gave an error on correct code label May 18, 2018
@JelleZijlstra
Copy link
Member

Seems like this is fixed. This variation of the OP's post:

from typing import *

class DictWrapper(dict):

    @classmethod
    def fromkeys(cls, iterable, value=None):
        # type: (Iterable, Union[Any, Callable]) -> DictWrapper
        if not callable(value):
            return DictWrapper(super(DictWrapper, cls).fromkeys(iterable, value))

        def _():
            for key in iterable:
                yield key, value(key)

        return DictWrapper(_())

produces no errors on current mypy

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong false-positive mypy gave an error on correct code priority-1-normal
Projects
None yet
Development

No branches or pull requests

5 participants