From your initial assignment (100), v variable is of type int. When you modify its value to 200, this is still of type int. However, once you change it to 3.14, it is of type float. Then for “Hello”, which is of type str.
For the function, I think that it has to do with the variables having local scope (not global like the first example) and the fact that you did not type hint either the parameter types or the return type of the function.
If functions or methods are not type hinted at all (e.g. no return type too), they are ignored by type checkers by default, and when called have a signature of (*args: Any, **kwargs: Any) -> Any, or in this case (x: Any = ...) -> Any.
See this mypy playground example for more.
from typing import reveal_type
def a(x=10000):
return x*x
def b(x: int = 10000) -> int:
return x*x
reveal_type(a)
reveal_type(b)
main.py:10: note: Revealed type is "def (x: Any =) -> Any"
main.py:11: note: Revealed type is "def (x: builtins.int =) -> builtins.int"
Success: no issues found in 1 source file
Mypy’s being conservative. The correct thing to do is to provide a type signature for the function.
The function could be called later on with any argument, and while x is not None is inferred after the if statement, we could probably have an argument about what should be inferred about the function signature from the following alone:
def func(x=None):
if x is None:
#do default
return
# use x not None