I'm surprised to see the even split on the last case, since my intuition is it should behave the same as the Union case where everyone narrows `x` to `int`. Can anyone from mypy/pyright shed some light on the reasoning there? I assume it has to do with Any being a special case, but I'd like to hear others' thoughts on it. -- Teddy On Wed, Sep 2, 2020 at 11:26 AM Guido van Rossum <guido@python.org> wrote:
Consider these two similar functions: ``` from typing import Union
def f() -> int: x: Union[int, str] = 42 return x # Error here
def g() -> int: x: Union[int, str] x = 42 return x # But not here ``` Quite a while ago (2016-2017) there was a long discussion about this in the mypy tracker: https://github.com/python/mypy/issues/2008
Not only is it surprising that these two functions are type-checked differently, there are differences across type checkers. I tried mypy, pytype, pyre and pyright. All of them consider the second function correct. But all except pyright produce a type error on the first function, something along the lines of ``` t.py:5: error: Incompatible return value type (got "Union[int, str]", expected "int") ``` (It's possible that there are configuration settings to change the behavior; I didn't look into this.)
I think it would be in everybody's interest if all type checkers agreed on this. I also think it's surprising to users that the two functions are treated differently. (But as the old mypy issue shows, not everybody agrees they should be treated the same either. :-)
There's another twist (note the return type is str here): ``` from typing import Any
def h() -> str: x: Any = 42 return x ``` This is an error in pyre but not in mypy, pytype or pyright. And for good measure the other variant: ``` def i() -> str: x: Any x = 42 return x ``` This is accepted by mypy and pyright, but an error to pyre and pytype.
To summarize, it seems the type of x will be as follows: ``` x: Union[int, str] = 42 # mypy: Union; pytype: Union; pyre: Union; pyright: int # majority doesn't narrow
x: Union[int, str] x = 42 # mypy: int; pytype: int; pyre: int; pyright: int # everybody narrows
x: Any = 42 # mypy: Any; pytype: Any; pyre: int; pyright: Any # majority doesn't narrow
x: Any x = 42 # mypy: Any; pytype: int; pyre: int; pyright: Any # even split ```
Looking at this, I'd say if we follow the majority, we would have to make the following changes:
- pyright should stop narrowing for `x: Union[..] = value` - pyre should stop narrowing for `x: Any = value` - mypy and pyright should start narrowing for `x: Any; x = value`
(The latter recommendation is debatable, since it's an even split, but I like it better if Union and Any are treated similarly in this case.)
Let the debate begin.
-- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...> _______________________________________________ Typing-sig mailing list -- typing-sig@python.org To unsubscribe send an email to typing-sig-leave@python.org https://mail.python.org/mailman3/lists/typing-sig.python.org/ Member address: tsudol@google.com