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

Conditional expression in "with" statement inferred as 'object', lacking __enter__ and __exit__ #5512

Closed
chkno opened this issue Aug 20, 2018 · 4 comments
Labels
bug mypy got something wrong false-positive mypy gave an error on correct code priority-1-normal topic-join-v-union Using join vs. using unions topic-ternary-expression a if b else c

Comments

@chkno
Copy link

chkno commented Aug 20, 2018

from tempfile import TemporaryDirectory, TemporaryFile
import sys

use_file = 'directory' not in sys.argv

with (TemporaryFile() if use_file else TemporaryDirectory()) as thing:
    print(thing)

Mypy infers the type of the conditional expression as object rather than Union[IO,TemporaryDirectory]

$ mypy multi_with.py

multi_with.py:6: error: "object" has no attribute "__enter__"
multi_with.py:6: error: "object" has no attribute "__exit__"

Explicitly typing the result of the conditional expression makes the error messages go away:

named_intermediate: Union[IO, TemporaryDirectory] = (TemporaryFile() if use_file else TemporaryDirectory())

with named_intermediate as thing:
    print(thing)

I observe this in both mypy versions I tried: 0.600 and 0.620

These past issues and pull requests look relevant:
#3487 Type of conditional expression is join instead of union
#5041 Fix type of conditional statement to Union and not Join.
#5095 Don't always infer unions for conditional expressions

@ilevkivskyi
Copy link
Member

Yes, one option is to infer a union for conditional expression. Another option however is to still use join, but fix #3830 (at leat for the situation where we have a protocol context, like ContextManager in this case, which should be pretty straightforward)

@ilevkivskyi ilevkivskyi added bug mypy got something wrong priority-1-normal false-positive mypy gave an error on correct code labels Aug 23, 2018
@indigoviolet
Copy link

indigoviolet commented Mar 21, 2021

This bug still seems to be open in mypy 0.812: https://mypy-play.net/?mypy=latest&python=3.9&gist=35daf188cbaa119b95c77522250a6081

I don't quite understand why

  • typing the expression as ContextManager[None] doesn't suffice/work
  • why assigning in an if block instead of the if else expression is different

Anyway, @ilevkivskyi's #5512 (comment) doesn't seem to be relevant any longer.

@MattiasMartens
Copy link

Still open as of 0.942.

For reference of contemporary Googlers, the specific error message has changed:

error: "Iterator[None]" has no attribute "__enter__"; maybe "__iter__"?

@ilevkivskyi
Copy link
Member

The original example now works on master.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong false-positive mypy gave an error on correct code priority-1-normal topic-join-v-union Using join vs. using unions topic-ternary-expression a if b else c
Projects
None yet
Development

No branches or pull requests

6 participants