Skip to content

Conversation

msullivan
Copy link
Collaborator

This fixes an issue where the Any that is inferred temporarily when a
node is deferred could cause a bad overload to be picked and produce
a spurious error even though it checked properly the second time.

…rred

This fixes an issue where the Any that is inferred temporarily when a
node is deferred could cause a bad overload to be picked and produce
a spurious error even though it checked properly the *second* time.
@msullivan msullivan requested review from JukkaL and ilevkivskyi May 18, 2019 01:29
Copy link
Member

@ilevkivskyi ilevkivskyi left a comment

Choose a reason for hiding this comment

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

Thanks!

In general the solution looks right, but there is one thing that disturbs me a bit. While the overload overhaul last year we specifically took care about the case where an argument to an overloaded function is Any. If there are more that one matching overload, we should return Any to avoid further false positives. Does this mean that there is a breach in our logic? cc @Michael0x2a

_S = TypeVar('_S')
_T = TypeVar('_T')
_R = TypeVar('_R')
_F = TypeVar('_F', bound=Callable[..., Any])
Copy link
Member

Choose a reason for hiding this comment

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

This type variable is not used in the test.

def partial(*args: Any) -> Any:
pass


Copy link
Member

Choose a reason for hiding this comment

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

One space would be enough.

@@ -3276,7 +3276,7 @@ def accept(self,
has_any_type(typ)):
self.msg.disallowed_any_type(typ, node)

if not self.chk.in_checked_function():
if not self.chk.in_checked_function() or self.chk.current_node_deferred:
Copy link
Member

Choose a reason for hiding this comment

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

I would return TypeOfAny.special_form for the latter case.

@Michael0x2a
Copy link
Collaborator

@ilevkivskyi -- I did a bit of digging, and it seems the breach you were talking about is rooted in how we're computing the arg_contains_any variable here: https://github.com/python/mypy/blob/master/mypy/checkexpr.py#L1445

When you try running the test case in this PR, the args are of type Any and int on the first iteration, but this variable ended up being set to False. (So, the usual "if an arg is Any, return Any" logic ended up not running.)

It turned out the reason for this is that has_any_type is designed to ignore special_form Anys: https://github.com/python/mypy/blob/master/mypy/checkexpr.py#L3518.

Not sure if/how this should be fixed -- I'm not very familiar with what the node-deferring semantics are supposed to be. Maybe we could add a new TypeOfAny for deferred nodes, or maybe we could add a check to the overload logic to return early if a node is deferred? Or maybe Sully's fix is still the best approach overall.

@JukkaL
Copy link
Collaborator

JukkaL commented May 20, 2019

I'm going to merge this as is, since we need this at Dropbox urgently. The improvements discussed above may make sense as separate PRs.

@JukkaL JukkaL merged commit 11331eb into master May 20, 2019
@msullivan msullivan deleted the fix-defer-overloads branch May 20, 2019 20:53
@ilevkivskyi
Copy link
Member

@Michael0x2a Coming back to this I think we can live with this fix as is. I will only submit a PR with minor tests cleanups I suggested.

ilevkivskyi added a commit to ilevkivskyi/mypy that referenced this pull request Jun 2, 2019
msullivan pushed a commit that referenced this pull request Jun 2, 2019
PattenR pushed a commit to PattenR/mypy that referenced this pull request Jun 23, 2019
…rred (python#6860)

This fixes an issue where the Any that is inferred temporarily when a
node is deferred could cause a bad overload to be picked and produce
a spurious error even though it checked properly the *second* time.
PattenR pushed a commit to PattenR/mypy that referenced this pull request Jun 23, 2019
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.

4 participants