Skip to content

Nested functions don't take type restrictions into account #2145

Description

@gvanrossum

Example:

from typing import *

def f(a: Union[int, str]) -> int:
    if isinstance(a, str):
        return -1
    def inner() -> int:
        return a+1  # E: Unsupported operand types for + ("Union[int, str]" and "int"
    return inner()

Note that when inner() is defined, and also when it's called, a can only be an int. But we still get an error.

I ran into this when checking some real-world code against strict optional -- there the union was Optional[int] and the type restriction was if a is not None, but it's the same problem.

Activity

  1. ddfisher commented on Oct 22, 2016

    @ddfisher
    Collaborator

    I think this is quite difficult to do correctly. This is correct because f exits before inner is defined, but wouldn't be correct for other local information about types. For example:

    from typing import *
    
    def f(a: Union[int, str]) -> int:
        if isinstance(a, str):
            return -1
        else:
            def inner() -> int:
                return a+1  # E: Unsupported operand types for + ("Union[int, str]" and "int"
        a = "foo"
        return inner()

    The binder doesn't keep track of this information at the moment -- I'm not sure how hard it would be to add, but probably not super easy.

  2. gvanrossum commented on Oct 22, 2016

    @gvanrossum
    MemberAuthor

    I see. I'm fine with closing this then.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions