Python gradual typing

81 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 answers

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