Python gradual typing

117 Views Asked by At

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:

  1. y is not annotated, therefore it is of type Any
  2. cast Any to str
  3. 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

1

There are 1 best solutions below

0
On BEST ANSWER

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).