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

Conditional expression type inference behaves unexpectedly #622

Closed
JukkaL opened this issue Mar 24, 2015 · 4 comments
Closed

Conditional expression type inference behaves unexpectedly #622

JukkaL opened this issue Mar 24, 2015 · 4 comments
Labels

Comments

@JukkaL
Copy link
Collaborator

JukkaL commented Mar 24, 2015

The type of the conditional expression 1 if foo else 'x' is object, which is totally unexpected.

To be consistent with the rest of the language, the type should be one of these:

  1. Union[int, str] (obvious)
  2. Error, unless the type context is a supertype of both int and str. If one of the operands would have type None, the type will always be Optional[...] once mypy supports strict type checking of None values (None would be the only special case).

The rationale for case 2 is that mypy usually tries not to infer non-trivial union types, as these can result in confusing error messages far away from the source of the error. The error would be given if the only common non-union, non-Any supertype of the operands would be object. This is a somewhat arbitrary heuristic, but it would probably work well in most cases.

(These are also sometimes called ternary expressions. -- SEO Guido)

@JukkaL JukkaL added the bug mypy got something wrong label Mar 24, 2015
@JukkaL
Copy link
Collaborator Author

JukkaL commented Mar 24, 2015

This was motivated by an example on the python-ideas mailing list.

@gvanrossum
Copy link
Member

What exactly is the context? Assuming the following two examples would work, (2) sounds good:

  • Using a type comment:
x = 'no' if a < 0 else sqrt(a)  # type: Union[str, float]
  • Using a pre-declared type:
x = Undefined(Union[str, float])
x = 'no' if a < 0 else sqrt(a)

@JukkaL
Copy link
Collaborator Author

JukkaL commented Mar 25, 2015

Both would work. Examples of type context (yeah, this should be documented better):

  • In assignment x = expr, the type context of expr is the type of x (unless this assignment initializes x).
  • In assignment x = expr # type: T, the type context of expr is T.
  • In call f(expr), the type context of expr is the type of the first argument of f.
  • In return expr, the type context of expr is the declared return type of the enclosing function.

@ilevkivskyi
Copy link
Member

This is superseded by #3487

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

No branches or pull requests

3 participants