-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
document ternary/conditional type inference limitations #6649
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I have few suggestions.
docs/source/common_issues.rst
Outdated
|
||
.. code-block:: python | ||
|
||
def f(x: AnyStr, y: AnyStr) -> bytes: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The example with AnyStr
is not the best one, since it combines two tricky points:
- the one you are explaining
- the fact that functions generic in variables with restrictions are type checked multiple times.
I would rather use a single argument function with a Union[str, bytes]
argument.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, if I try to simplify this down to
def f(x: Union[str, bytes]) -> bytes:
r = x.encode('ascii') if isinstance(x, str) else x
# results in 'error: "bytes" has no attribute "encode"; maybe "decode"?'
if isinstance(x, str):
r = x.encode('ascii') # whereas Mypy can narrow within an if statement
else:
r = x
return r
Mypy doesn't error at all, which is quite interesting. Whereas if I use AnyStr on that same argument, there is an error.
It may be that I have oversimplified the explanation for what is going on?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To clarify, mypy can restrict types using isinstance()
in ternary expressions, but it cannot consider sub-expressions of ternary expression unreachable. Here is even simpler example:
x: bytes
if isinstance(x, str):
r = x.encode() # OK, this is unreachable
else:
r = x
r = x.encode() if isinstance(x, str) else x # Error here
Closing since there has been no activity in a long time. Feel free to repopen if you want to continue working on this. |
As per the discussion in #4134 , it seems worth documenting that conditional expressions don't always work smoothly with type inference. This PR makes sure to include the word ternary and conditional so that page/doc searches will turn up an explanation for this behavior in case anyone is searching for it.