As far as I know, Python is a gradual typing language. And all unannotated variables are of type Any which is a supertype and subtype of any type. Why then is the following code rejected by the static type checker?
def doubles(x: str) -> str:
return x + x
y = True
doubles(y)
I understand that the program is obviously incorrect, but how did the type checker guess? Shouldn’t the following happen:
yis not annotated, therefore it is of type Any- cast
Anytostr - accept the program
The expected behavior occurs only if you explicitly specify the Any type. I would assume that without explicitly specifying Any, y would be assigned the type of the right expression, that is, bool, but then we would not be able to change the value of y to 123 type int, which is not true
>Solution :
The static type checking system will also "look into" actually assigned values in the source code. And will, in fact, adopt the type of assigned values to un-annotated variables.
In your example, it "sees" just as we can do, y contains a bool. And even if y would be annotated as being bool | str, it would see the actual contained value in this case is a bool. (But it actually complains about the broader type).
Moreover, it won’t allow simply "more broad" values to fit into narrower annotated calls: even if you do annotate y as "any", fetch its value at runtime from somewhere the static typing system can’t "see", it will could warn you with such a call: doubles requires a str parameter (but it actually allows it, at least mypy).