'All python helper causing mypy to think field is optional

When using the python all() helper I am seeing odd behaviour with mypy (version 0.942) where it thinks a field is optional even though the all() helper would make sure all of them exist.

For the following code snippet I am seeing odd behavior from mypy

def rate_limit(user_id: int, rate_limit_max: int, rate_limit_since_time: int):
    do_something()

def some_func(
    user_id: int = None, 
    rate_limit_max: int = None, 
    rate_limit_since_time: int = None
): 
    if all([user_id, rate_limit_max, rate_limit_since_time]):
        rate_limit(user_id, rate_limit_max, rate_limit_since_time)

For this code snippet I get something along these lines:

error: Argument "user_id" to "rate_limit" has incompatible type "Optional[int]"; expected "int"


Solution 1:[1]

Based on the docs juanpa provided above I was able to find (PEP-647) looks like mypy can't figure out what the type returned from the all() helper would be.

From the docs

There are cases where type narrowing cannot be applied based on static information only. Consider the following example:

def is_str_list(val: List[object]) -> bool:
    """Determines whether all objects in the list are strings"""
    return all(isinstance(x, str) for x in val)

def func1(val: List[object]):
    if is_str_list(val):
        print(" ".join(val)) # Error: invalid type

This code is correct, but a type checker will report a type error because > the value val passed to the join method is understood to be of type List[object]. The type checker does not have enough information to statically verify that the type of val is List[str] at this point.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Christopher Forsythe