Skip to content

Inconsistency in Union/promotion interactions #6168

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

Closed
msullivan opened this issue Jan 8, 2019 · 3 comments
Closed

Inconsistency in Union/promotion interactions #6168

msullivan opened this issue Jan 8, 2019 · 3 comments

Comments

@msullivan
Copy link
Collaborator

In the following test

from typing import Union

class A:
    x: Union[int, float]

def foo(x: Union[int, float], y: A) -> None:
    reveal_type(x)
    reveal_type(y.x)

we emit:

lol.py:8: error: Revealed type is 'Union[builtins.int, builtins.float]'
lol.py:9: error: Revealed type is 'builtins.float'

That is to say, class attributes have unions simplified using promotions while arguments (and locals) do not.

Probably they ought to have the same behavior?
(And probably the behavior ought to be to not simplify, especially because of #6114)

msullivan added a commit that referenced this issue Jan 8, 2019
The type of Num.n is `complex`, though it can in practice also be an
`int` or a `float`, and we case on the actual type to determine which
sort of mypy ast node to use.

In #6114, promotions were disabled in `isinstance` checks, which
caused mypy to decide that the `isinstance` checks for int and float
won't match. Fix this by giving the value the type object instead of
complex.

Typeshed *does* actually annotate `n` as `Union[float, int, complex]`,
but mypy simplifies that into `complex`. (It does *not* do this
simplification for local variables with such an annotation; see
issue #6168.)
msullivan added a commit that referenced this issue Jan 9, 2019
The type of Num.n is `complex`, though it can in practice also be an
`int` or a `float`, and we case on the actual type to determine which
sort of mypy ast node to use.

In #6114, promotions were disabled in `isinstance` checks, which
caused mypy to decide that the `isinstance` checks for int and float
won't match. Fix this by giving the value the type object instead of
complex.

Typeshed *does* actually annotate `n` as `Union[float, int, complex]`,
but mypy simplifies that into `complex`. (It does *not* do this
simplification for local variables with such an annotation; see
issue #6168.)
@ilevkivskyi
Copy link
Member

And probably the behavior ought to be to not simplify

Yes, I think we should never use promotions in union simplification. Also this looks like something that may be easy to fix. We just need to use ignore_promotions=True in UnionType.make_simplified_union().

@ilevkivskyi
Copy link
Member

Added usability label because this can cause confusion, see #7241.

@hauntsaninja
Copy link
Collaborator

These currently have the same type

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants