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

Fix partially defined in the case of missing type maps #15995

Merged
merged 1 commit into from
Oct 10, 2023

Conversation

hauntsaninja
Copy link
Collaborator

@hauntsaninja hauntsaninja commented Aug 30, 2023

Thanks @AlexWaygood for sending me on this adventure. This took me a while for me to debug!

When we don't need to warn about unreachable code, we don't end up calling self.is_noop_for_reachability(s) (which is meant to tell us whether the code should be warned about or is raise AssertionError or typing.assert_never(never) or something).

if not self.should_report_unreachable_issues():

This innocuous check has a side effect that turns out to be important for the partially undefined checks. These checks work by reaching into the type map populated by the checker. But if we never actually ended up analysing the code, we never populate the type map.

This therefore changes things to assume that if we couldn't find the expression in the type map, it's probably because it was unreachable.

Thanks @AlexWaygood for sending me on this adventure. This took me a
while to debug!

It turns out when we don't need to warn about unreachable code, we don't
end up calling `self.is_noop_for_reachability(s)` (which is meant to
tell us whether the code should be warned about or is
`raise AssertionError` or `typing.assert_never(never)` or something.
https://github.com/python/mypy/blob/6f650cff9ab21f81069e0ae30c92eae94219ea63/mypy/checker.py#L2748

This innocuous check has a side effect that turns out to be important
for the partially undefined checks. These checks work by reaching
into the type map populated by the checker. But if we never actually
ended up analysing the code, we never populate the type map.

This therefore changes things to assume that if we couldn't find the
expression in the type map, it's probably because it was unreachable.
@github-actions
Copy link
Contributor

According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅

@AlexWaygood
Copy link
Member

Thanks @AlexWaygood for sending me on this adventure. This took me a while to debug!

Thanks so much for digging into this! :D

Comment on lines +1030 to +1045
[case testUnreachableCausingMissingTypeMap]
# flags: --enable-error-code possibly-undefined --enable-error-code used-before-def --no-warn-unreachable
# Regression test for https://github.com/python/mypy/issues/15958
from typing import Union, NoReturn

def assert_never(__x: NoReturn) -> NoReturn: ...

def foo(x: Union[int, str]) -> None:
if isinstance(x, str):
f = "foo"
elif isinstance(x, int):
f = "bar"
else:
assert_never(x)
f # OK
[builtins fixtures/tuple.pyi]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be worth adding a match/case test as well, or would that just be unnecessarily duplicative?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good q, I think just duplicative. (fwiw I'd changed to if since that runs on all Python versions)

@hauntsaninja hauntsaninja merged commit 8b6d213 into python:master Oct 10, 2023
18 checks passed
@hauntsaninja hauntsaninja deleted the partial-defin branch October 10, 2023 06:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants