Skip to content

isinstance checks cause type declarations to leak from the binder #1568

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
ddfisher opened this issue May 24, 2016 · 10 comments
Closed

isinstance checks cause type declarations to leak from the binder #1568

ddfisher opened this issue May 24, 2016 · 10 comments
Labels
bug mypy got something wrong

Comments

@ddfisher
Copy link
Collaborator

The problem with this is most easily visible with list comprehensions:

lst = [1, 2, 3]  # type: List[Union[int, str]]
[x if isinstance(x, int) else 0 for x in lst]
reveal_type([x for x in [4, 5, 6]])
$ python3 -m mypy ~/test.py
test.py:3: error: Revealed type is 'builtins.list[Union[builtins.int, builtins.str]]'

This happens because of this line in the binder, which always adds the declared type of a variable to the topmost frame whenever a binding for it is pushed: https://github.com/python/mypy/blob/master/mypy/checker.py#L127

This is obviously a bug, but it's not yet clear what the best way to fix the issue is. The binder is small, but complicated -- perhaps the best fix is it rewrite it in a more understandable/robust way?

This issue is the reason mypy still has a self-typecheck error with #1562.

@ddfisher ddfisher added the bug mypy got something wrong label May 24, 2016
@gvanrossum
Copy link
Member

gvanrossum commented May 24, 2016 via email

@ddfisher
Copy link
Collaborator Author

Right. But I think I'd be pretty reasonable to tell people not to use that in Python 2.

@rwbarton
Copy link
Contributor

Hi @ecprice :)

@rwbarton
Copy link
Contributor

#1044 looks like it might be the same issue.

@ecprice
Copy link
Contributor

ecprice commented Jun 22, 2016

I think the top commit of my typebinder branch fixes this. It probably cleanly applies to master, but I haven't checked.

@rwbarton rwbarton assigned rwbarton and unassigned rwbarton Jun 26, 2016
@rwbarton
Copy link
Contributor

I'm actually not going to fix this right now, in part because the correct behavior isn't entirely clear; should we treat comprehension loop variables as deleted after the comprehension (maybe only in Python 2 mode)?

@gvanrossum
Copy link
Member

gvanrossum commented Jun 29, 2016 via email

@rwbarton
Copy link
Contributor

Oh right and there's also the tricky bit that while list comprehensions are evaluated immediately (of course), only the first sequence in a generator comprehension is evaluated immediately. So technically we should not use information from the binder for any sequence expression past the first. (Like we don't use information from the binder when checking the body of a lambda, since the variables it refers to may have changed value by the time the lambda is executed.)

@elazarg
Copy link
Contributor

elazarg commented Apr 3, 2017

The output now is error: Revealed type is 'builtins.list[builtins.int*]' as I assume it should be.

@ilevkivskyi
Copy link
Member

I am not sure how this got fixed, but the current behaviour looks right to me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong
Projects
None yet
Development

No branches or pull requests

6 participants