如何在使用输入模块时检查类型兼容性?

时间:2016-06-20 00:05:45

标签: python typing mypy

我正在使用Python PEP484类型提示为我用Python编写的DSL编写类型检查器。如果我的某个函数需要为其中一个参数设置类型T,并且使用类型S的表达式调用它,那么如何检查该调用是否有效?是否足够使用issubclass(S, T)?如果是这样,为什么mypy会进行如此复杂的is_subtype检查?或者我应该只使用mypy版本吗?

编辑:这是一个澄清我的意思的例子。 DSL具有定义为:

的功能
T = TypeVar('T', float, str)
def op_add(operand1: T, operand2: T) -> T:
    "Number addition or string concatenation."
    # In this DSL, `+` cannot be used with lists
    return operand1 + operand2  # Rely on Python overloading of `+`

然后,用户键入一个表达式,该表达式被解析为语法树,其分支可以是:node = OperatorNode('+', Literal([5.0]), Variable("abc"))。我们尚未知道abc变量的值,但列表永远不能与+一起使用,因此我想提出一个TypeError来提醒用户。

如果我issubclass(typing.List[float], var),那会给我假,所以我可以马上提出错误。我的问题是,当我构建DSL时,或者如果我需要使用更复杂的检查,例如mypy

,这种检查是否可以保证在各种情况下都有效

1 个答案:

答案 0 :(得分:2)

如果issubclass的参数都不包含来自issubclass模块的构造,例如typingUnionCallable,泛型,那么

Any检查就足够了等等。

typing构造在python运行时中作为其真实形式的阴影存在,也就是说它们不支持许多在概念上有意义的操作:

issubclass(List[int], List[int])  # runtimem error
issubclass(List[int], List) # True (as expected)
issubclass(str, Union[str]) # runtime error
issubclass(Union[str], str) # True (as expected)
issubclass(Union[int, str], str) # runtime error

有时issubclass将与typing构造一起使用,但一般情况下,它可能引发异常或给出错误的答案;你需要根据具体情况弄清楚要做什么。

mypy有一个更复杂的is_subtype,因为它确实需要处理所有typing构造,即使这样,仍然有一些工作要做。