Skip to content

Fix leaking error messages during overload selection #5211

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

Conversation

Michael0x2a
Copy link
Collaborator

Fixes #5210 (?)

When mypy tries selecting an appropriate overload alternative, it swaps out the current 'msg' object with a placeholder. If this placeholder does not accumulate any error messages, we know that alternative is a successful match.

Previously, we replaced only checkexpr.ExpressionChecker's msg object with the placeholder. However, since checkexpr can sometimes call checker.TypeChecker, we need to replace its msg object as well to prevent error messages that would normally be silenced from leaking.

More broadly, the current overload implementation broke the invariant that both msg fields refer to the same underlying MessageBuilder object. This pull request fixes that oversight.

Fixes python#5210 (?)

When mypy tries selecting an appropriate overload alternative, it swaps
out the current 'msg' object with a placeholder. If this placeholder
does not accumulate any error messages, we know that alternative is a
successful match.

Previously, we replaced only checkexpr.ExpressionChecker's msg object
with the placeholder. However, since checkexpr can sometimes call
checker.TypeChecker, we need to replace its msg object as well to
prevent error messages that would normally be silenced from leaking.

More broadly, the current overload implementation broke the invariant
that both msg fields refer to the same underlying MessageBuilder object.
This pull request fixes that oversight.
@Michael0x2a
Copy link
Collaborator Author

@gvanrossum -- I think this fixes the bug you found earlier -- do you mind re-testing w/ these changes?

Also, the way that I'm currently "capturing" the error messages feels pretty janky. Do you know if there's some better way of doing what the code is currently doing?

(If not, I think we maybe should sometime in the future? It sort of feels like the codebase has several different ad-hoc ways of "capturing" or "conditionally silencing" errors and it might be nice to unify these different approaches in a more flexible way somehow -- maybe as part of a larger refactoring on how we handle error messages in general? /aside)

@@ -1238,7 +1238,9 @@ def infer_overload_return_type(self,
for typ in plausible_targets:
overload_messages = self.msg.clean_copy()
prev_messages = self.msg
assert self.msg is self.chk.msg
Copy link
Member

Choose a reason for hiding this comment

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

I think there's a slightly different pattern to ignore messages during a certain block of code, see e.g. checkmember.py L183. I'll test your code next.

Copy link
Member

@gvanrossum gvanrossum left a comment

Choose a reason for hiding this comment

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

OK, this does fix the errors I was seeing in the Dropbox code base. Thanks for the quick fix! Let me know if you want to change the message suppressing logic now too -- if not feel free to merge yourself.

@Michael0x2a Michael0x2a merged commit 402a066 into python:master Jun 13, 2018
@Michael0x2a Michael0x2a deleted the fix-leaking-error-messages-during-overload-selection branch June 13, 2018 02:42
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.

map with lambda is broken in Python 2; gives '<Erased>' object is not iterable
2 participants