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 make_simplified_union interaction with Any #2714

Closed
wants to merge 1 commit into from

Conversation

JukkaL
Copy link
Collaborator

@JukkaL JukkaL commented Jan 19, 2017

DO NOT MERGE YET -- this causes errors in internal Dropbox
repos.

(This is an updated version of #2197 by ddfisher.)

Fixes #2712.

make_simplified_union had two incorrect interactions with Any that this
fixes:

  1. Any unions containing Any were simplified to Any, which is incorrect.
  2. Any classes that inherited from Any would be removed from the union
    by the subclass simplification (because subclasses of Any are
    considered subclasses of all other classes due to subtype/compatible
    with confusion).

Note that Unions call make_union and not make_simplified_union, so
this doesn't change their behavior directly (unless they interact with
something else which causes them to be simplified, like being part of
an Optional).

(This is an updated version of #2197 by ddfisher.)

make_simplified_union had two incorrect interactions with Any that this
fixes:
1) Any unions containing Any were simplified to Any, which is incorrect.
2) Any classes that inherited from Any would be removed from the union
by the subclass simplification (because subclasses of Any are
considered subclasses of all other classes due to subtype/compatible
with confusion).

Note that `Union`s call make_union and not make_simplified_union, so
this doesn't change their behavior directly (unless they interact with
something else which causes them to be simplified, like being part of
an `Optional`).
@JukkaL
Copy link
Collaborator Author

JukkaL commented Jan 19, 2017

I'm thinking about first merging a simplified version of this that is just enough to fix #2712.

JukkaL added a commit that referenced this pull request Jan 19, 2017
In particular, this helps with classes that have Any base classes.

This is enough to fix #2712. This is almost a subset of #2714
and should land before that, as this should cause less disruption.
@ddfisher ddfisher self-requested a review January 19, 2017 20:31
if msg.num_messages() != old_num_messages and any(isinstance(t, AnyType)
for t in results):
# If there was an error, return AnyType to avoid generating multiple messages for the
# same error.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Was this not a problem before?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This fixes a regression in testUnionAndBinaryOperation (and another test case whose name I can't remember right now). Previously, if some of the results was Any, the result got simplified into Any. Without this change, we'd preserve the non-Any types and this would sometimes produce a duplicate, similar-looking error message about the same binary operation, which would be a regression. Now the code falls back to the old behavior in these cases, and since this only happens when we have already generated a message, it doesn't affect correctness, just the specific messages generated for type errors involving union types.

if s == t:
return s
if isinstance(t, AnyType):
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why this change? What effect does it have overall?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Without this, testUnionAnyIsInstance will fail -- the type in the else block will be Union[int, Any], though it should be Any. This makes is possible to narrow down from Union[int, Any] to Any, and this is the only place where this code is used. Previously this worked (probably accidentally) because Union[int, Any] got simplified to just Any. This won't have any other effect, as far I can see.

gvanrossum pushed a commit that referenced this pull request Jan 20, 2017
In particular, this helps with classes that have Any base classes.

This is enough to fix #2712. This is almost a subset of #2714
and should land before that, as this should cause less disruption.
@JukkaL
Copy link
Collaborator Author

JukkaL commented Jan 23, 2017

I now feel that this approach is not quite right. A better way to simplify union may be use a subtype check that doesn't treat Any specially. We already have is_proper_subtype but it's very incomplete and probably not sufficient right now. I'll write more about this later.

@JukkaL
Copy link
Collaborator Author

JukkaL commented Mar 21, 2017

Closing in favor of #3025.

@JukkaL JukkaL closed this Mar 21, 2017
@gvanrossum gvanrossum deleted the fix-simplified-union-2 branch March 24, 2017 17: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.

Union of a class with Any base and None is sometimes None
2 participants