Skip to content
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

cannot infer (or provide) types of lambdas #4226

Open
bwo opened this issue Nov 8, 2017 · 5 comments

Comments

@bwo
Copy link
Contributor

@bwo bwo commented Nov 8, 2017

Consider this file: https://gist.github.com/bwo/077400d43c517ca0b80f2e85f615073e
The output from running mypy is:

comp.py:57: error: Cannot infer type argument 1 of "cfilter"
comp.py:61: error: Revealed type is 'typing.Sequence*[Any]'
comp.py:67: error: Cannot infer type argument 1 of "cmap"
comp.py:68: error: Revealed type is 'def (typing.Sequence*[Any]) -> typing.Sequence*[builtins.int*]'
comp.py:70: error: Revealed type is 'typing.Sequence*[builtins.int*]'
comp.py:72: error: Cannot infer type argument 3 of "comp"

I suspect this is related to the fact that reveal_type(len) and reveal_type(lambda s: len(s)) are, to my surprise, not the same (the latter accepts Any as input, the former requires Sized). According to mypy docs lambdas are subject to bidirectional typechecking, but afaict sufficient information is present in the file given to type the lambdas; nevertheless, they aren't.

@gvanrossum

This comment has been minimized.

Copy link
Member

@gvanrossum gvanrossum commented Nov 8, 2017

@bwo

This comment has been minimized.

Copy link
Contributor Author

@bwo bwo commented Nov 8, 2017

Replacing the partial calls with lambdas (or named functions) doesn't change the output. Also, I'm only using partial in the implementation of the type-overloaded functions, which I thought mypy wouldn't check, and the same inference failure occurs just with comp(lambda x: x + 1, lambda s: len(s)).

@gvanrossum

This comment has been minimized.

Copy link
Member

@gvanrossum gvanrossum commented Nov 9, 2017

@bwo

This comment has been minimized.

Copy link
Contributor Author

@bwo bwo commented Nov 9, 2017

from typing import Callable, TypeVar

S = TypeVar('S')
T = TypeVar('T')
U = TypeVar('U')


def comp(g, f):
    # type: (Callable[[T], U], Callable[[S], T]) -> Callable[[S], U]
    def composed(x):
        # type : (S) -> U
        return g(f(x))
    return composed


def test(s):
    # type: (str) -> int

    len_and_inc = comp(lambda i: i + 1, lambda s: len(s))
    x = len_and_inc(s)
    reveal_type(x)
    return x

revealed type is Any. Replacing lambda s: len(s) with len reveals a type of int. Replacing len_and_inc = comp(lambda i: i+ 1, lambda s: len(s)) with just len_and_inc = lambda s: len(s) reveals a type of int as well.

@gvanrossum

This comment has been minimized.

Copy link
Member

@gvanrossum gvanrossum commented Nov 9, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.