当类型处于允许类型的并集中时,不兼容的类型?

时间:2019-05-24 07:31:31

标签: python-3.x mypy

鉴于以下错误消息,我试图找出为什么mypy不喜欢此调用和签名组合的原因

to_json = self._format_types(to_json)

一个呼叫

def _format_types(
    self,
    to_format: Union[List, Dict]) -> Union[
        List, Dict, bytes, str, int, float]:

功能签名为

export PATH=$PATH:/usr/local/go/bin

1 个答案:

答案 0 :(得分:0)

如果先前推断to_json的类型为Dict[Any, Any],则这意味着编写这样的代码肯定应该是类型安全的:

to_json = self._format_types(to_json)
print(to_json.items())  # Danger!

但是,如果您的_format_types方法返回一个int而不是Dict[Any, Any]怎么办?这将导致上述程序崩溃,因此mypy报告分配不安全。

如果您完全确定调用self._format_types的特定方式将始终产生命令,则可以断言是这样:

temp = self._format_types(to_json)
assert isinstance(temp, dict)
to_json = temp
print(to_json.items())  # Safe!

...或者如果您更喜欢单行和/或不希望实际上的开销执行运行时检查,则只需转换表达式:

from typing import cast

# ...snip...

to_json = cast(Dict[Any, Any], self._format_types(to_json))
print(to_json.items())  # Also reported as safe!

或者,您可以尝试使用--allow-redefinition flag,在某些情况下,重新分配to_json后,mypy的类型会变大。

这样可以修改mypy的行为以执行以下操作:

def blah(self, to_json: Dict[Any, Any]) -> None:
    # This will continue to type check
    print(to_json.items())

    # Previously this would have caused an error; mypy will instead alter
    # the type of `to_json` to be your union if you use --allow-redefinition
    to_json = self._format_types(to_json)

    # And now, mypy will report an error since List, int, etc don't have
    # an 'item()' method:
    print(to_json.items())