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

Context manager __exit__ return type bool | None is treated as None for reachability analysis #15158

Open
VincentVanlaer opened this issue Apr 30, 2023 · 2 comments
Labels
bug mypy got something wrong topic-reachability Detecting unreachable code

Comments

@VincentVanlaer
Copy link
Contributor

Bug Report

The __exit__ method of a context manager indicates whether an exception should be propagated to the caller by either returning False or None if the exception should be propagated, or by returning True when the exception shouldn't be propagated. Mypy handles these cases w.r.t. reachability analysis as follows:

  • If the return type is None, then the context manager cannot suppress exceptions, hence if the with block unconditionally raises an exception or calls a NoReturn function, statements following after the with block are unreachable.
  • If the return type is bool, the context manager may suppress exceptions. Hence, statements after the with block are considered reachable, independent of what happens in the with block.
  • If the return type is bool | None, mypy treats this currently as the case where the return type is None.

I believe that if the return type is bool | None, mypy should consider this similar to the bool case, as it is possible for the context manager to suppress exceptions and be fine in terms of type checking.

To Reproduce

https://mypy-play.net/?mypy=master&python=3.11&flags=warn-unreachable&gist=579fa731e01cde87fc6ef9062de45d6c

Your Environment

  • Mypy version used: 1.2.0
  • Mypy command-line flags: --warn-unreachable
  • Python version used: 3.11
@VincentVanlaer VincentVanlaer added the bug mypy got something wrong label Apr 30, 2023
@AlexWaygood AlexWaygood added the topic-reachability Detecting unreachable code label Apr 30, 2023
@erictraut
Copy link

It occurs to me that it would be good to standardize the behavior across type checkers with respect to the interpretation of __exit__ return types. I see inconsistent use of Literal[True], Literal[False], bool, None, and union combinations of the above. I don't think this behavior of type checkers was ever standardized. Mypy was the first to implement this heuristic, so I've follow mypy's lead and matched its behavior in pyright. But there are some edge cases like bool | None where mypy's current behavior is questionable.

@VincentVanlaer, one of the challenges here is that in ambiguous cases, where a context manager might suppress exceptions based on some condition — or suppresses some subset of exceptions but not others, a static type checker needs to assume that all exceptions will be suppressed or none will be. Regardless of which assumption is made, both false positives and false negatives can result. Thankfully, most context managers either suppress all or suppress none.

@DetachHead
Copy link
Contributor

looks like the same issue as #8766

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

No branches or pull requests

4 participants