-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Description
While working on protocols, I noticed that stubs often use Any where object will be more appropriate and vice versa. Because of how protocol inference works and how current mypy solver works, this leads to problems since sometimes mypy infers Any instead of giving an error (maybe we could improve this by "tightening" solver?)
I think the root of the problem is that wee don't have a good story about Any. I believe the rules for interaction between Any and other things should be like this (where C is a normal class like int or str):
(1) join(Any, object) == object
(2) meet(Any, object) == Any
(3) join(Any, C) == C
(4) meet(Any, C) == C
(5) join(Any, NoReturn) == Any
(6) meet(Any, NoReturn) == NoReturnI use NoReturn for uninhabited type, since it is how it is currently called in PEP 484. The above rules could be summarized in a simple diagram:
object
|
Any (if it appears in a meet)
/ | \
... all other types ...
\ | /
Any (if it appear in a join)
|
NoReturn
Currently, mypy behaves in a completely different way, and I believe this is not right, let me explain why. We could focus on rules (3) and (4). Currently, mypy returns Any in both these cases. Here is why it is not safe:
from typing import Any
x = 'a'
y: Any = 1
lst = [x, y]
lst[0] >> 1 # not detected by mypy, fails at runtime, will be fixed by rule (3)
def f(x: int) -> None:
x >> 1
def g(x: Any) -> None:
pass
funs = [f, g]
funs[0]('a') # not detected by mypy, fails at runtime, will be fixed by rule (4)@JukkaL I will be grateful for your opinion.