caterinaurban / Typpete

34 stars 6 forks source link

Unsafe typing due to having None as subtype of all types #30

Closed mostafa-abdullah closed 7 years ago

mostafa-abdullah commented 7 years ago
def f(x, y):
    return x(y)

def a(x: int):
    return x

def b(x: str):
    return x

l = f(a, 1)
m = f(b, "str")

l += 1
m += 1

The type of f is inferred to be Callable[[Callable[[object], None], object], None] i.e. x arg is a function which takes an object and returns None y arg is object returns None

so variable l is inferred to be any super type of None which may be int, and so is m.

Accordingly the addition operations l += 1, m += 1 pass the type checking.

marcoeilers commented 7 years ago

I think there are several problems that IMO have nothing to do with None being a subtype of other types.

The first parameter of f cannot have the type Callable[[object], None] if f is called with the argument a. Both the parameter type and the return type are wrong. Since a takes an integer, it is wrong to treat it as a function that takes an object (more general). It would be okay the other way round, to treat it as a function that expects a bool (more specific).

Similarly, a can have the return type int or float or complex or object, and can subsequently be treated as something that returns something even more general (not more specific) than its actual return type. None is more specific than int, not more general.

Is it possible that subtyping between functions checks the subtype relations between parameters and return types the wrong way round?

mostafa-abdullah commented 7 years ago

Ooops you are right. I reversed the relationships. Sooorry :angel: