如何向 mypy 解释特定领域的约束

how to explain domain specific constraints to mypy

鉴于此片段:

from typing import Dict

def a(my_dict: Dict[str,int])->int:
    return my_dict.get('a') or my_dict.get('b')

我从领域知识中知道我必须有 a 或 b 键,而 mypy 不知道。因此我得到一个错误

error: Incompatible return value type (got Optional[int], expected int)

我如何告诉 mypy 这个事实?

我的任务是向现有的 python 代码库添加类型提示,因此我不想更改代码,只是添加类型注释。

dict.get(...) 方法的类型为 return 类型 Optional[ValueType]。确实没有办法解决这个问题。

如果您知道对 my_dict.get('b') 的调用总是会成功,您可以将其替换为 my_dict['b'],其 return 类型仅为 ValueType.所以,做:

from typing import Dict

def a(my_dict: Dict[str, int]) -> int:
    return my_dict.get('a') or my_dict['b']

Mypy 也理解断言(在某种程度上):

from typing import Dict

def a(my_dict: Dict[str, int]) -> int:
    ret_val = my_dict.get('a') or my_dict['b']
    assert ret_val is not None
    return ret_val

或者,您可以添加强制转换以强制 mypy 假定您的表达式具有特定类型。然而,这将是类型安全性最低的选项:您基本上是在覆盖类型检查器认为正确的内容。如果您绝对确定转换会成功,这很好,但我认为更好的选择是重构代码或至少添加运行时检查,就像我们对上面的断言所做的那样。

from typing import Dict, cast

def a(my_dict: Dict[str, int]) -> int:
    return cast(int, my_dict.get('a') or my_dict.get('b'))