为什么 PyCharm 没有捕获 Optional[int] 和 Optional[str] 之间的类型错误?

Why does PyCharm not catch type error between Optional[int] and Optional[str]?

我有点困惑为什么 PyCharm 不区分两种不同的可选类型。

考虑以下代码。

def funcs(foo:Optional[str]=None):
    print(foo)

def funci(var:Optional[int]=None):
    funcs(var)

argi = 1
args = "something"
argn = None

funcs(argi)
funcs(args)
funcs(argn)

请注意 funci 中的 funcs 调用没有发现将 Optional[int] 传递给正在寻找 Optional[str].[=21 的函数的问题=]

然而,如果我们删除 Optional[str] 检查会叫。

这是预期的行为吗?如果是,我该怎么办?

我的直觉告诉我,类型检查应该足够聪明,能够区分 Optional[str]Optional[int] 之间的区别。我通读了 PEP-526 and PEP-484 但没有用。

如果您在当前版本 PyCharm (2021.1) 中使用默认检查设置对此进行测试,则删除 funcs 参数中的 Optional 类型提示后的第二个警告是不再发布。

Is this expected behavior?

是的,linter 是正确的。类型必须完全兼容,否则可能会出现潜在错误,linter 会正确警告您。在更严格的意义上,PyCharm 也应该在第一种情况下发出警告,因为 strint.

之间存在潜在的不兼容性。

让我们使用 Mypy static type checker,因为它的结果通常更准确。

以下:

def funcs(foo: Optional[str] = None):
    pass

def funci(var: Optional[int] = None):
    funcs(var)

会导致Mypy报错:

your_module.py: error: Argument 1 to "funcs" has incompatible type "Optional[int]"; expected "Optional[str]"

If yes, what can I do about it?

Python 使用 gradual typing 意味着随着代码的进行,类型可以被检查并因此逐渐提示正确性。

如果您明确检查类型:

def funci(var: Optional[int] = None):
    if var is None:
        funcs(var)

Mypy 静态类型检查器没有发出错误。如果您确定在调用 funcs(var).

行之前该值将被限制为 None,则另一种方法也可以使用 cast