Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Non-optional outer variable becomes optional in inner function #5048

Closed
mjayfrancis opened this issue May 15, 2018 · 3 comments
Closed

Non-optional outer variable becomes optional in inner function #5048

mjayfrancis opened this issue May 15, 2018 · 3 comments

Comments

@mjayfrancis
Copy link

Mypy (0.600, default options - i.e. strict optional enabled) seems to get confused about the optionality of 'foo' in the below code:

from typing import Optional

class Foo:
    def bar(self) -> None:
         pass

def outer(foo: Optional[Foo]=None):
    foo = Foo()

    def inner() -> None:
        foo.bar()

reveal_type() shows that it correctly realises that 'foo' is no longer optional after the assignment in outer(), but for some reason it has become optional again in inner():

$ mypy foo.py 
foo.py:11: error: Item "None" of "Optional[Foo]" has no attribute "bar"

I know it's possible to overcome this by doing e.g. assert foo is not None, but it seems this case should work as is.

@JelleZijlstra
Copy link
Member

This has been discussed on the tracker before. I believe it's intended behavior; the reasoning is that you don't know in advance where in the outer function the inner function will be called, so you don't know what the restricted type of the variable is within the inner function.

@mjayfrancis
Copy link
Author

In this specific case the inference doesn't seem like it should be too hard - foo is set to a non-None value before inner() is defined, and not assigned to again afterwards.

Replacing None with a default value early in a function is quite a common pattern, as it's not always possible or desirable to set the "real default" in the function signature.

@ilevkivskyi
Copy link
Member

Duplicate of #2608

@ilevkivskyi ilevkivskyi marked this as a duplicate of #2608 May 15, 2018
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants