Skip to content

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

Closed

Description

@ddfisher

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.

Activity

  1. gvanrossum commented on May 24, 2016

    @gvanrossum
    Member
  2. ddfisher commented on May 24, 2016

    @ddfisher
    CollaboratorAuthor

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

  3. rwbarton commented on May 31, 2016

    @rwbarton
    Contributor

    Hi @ecprice :)

  4. rwbarton commented on Jun 22, 2016

    @rwbarton
    Contributor

    #1044 looks like it might be the same issue.

  5. ecprice commented on Jun 22, 2016

    @ecprice
    Contributor

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

  6. rwbarton commented on Jun 29, 2016

    @rwbarton
    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)?

  7. gvanrossum commented on Jun 29, 2016

    @gvanrossum
    Member
  8. rwbarton commented on Jun 29, 2016

    @rwbarton
    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.)

  9. elazarg commented on Apr 3, 2017

    @elazarg
    Contributor

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

  10. ilevkivskyi commented on Apr 3, 2017

    @ilevkivskyi
    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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrong

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions