如何修复 mypy 错误 "Expression has type Any [misc]",用于 python 类型提示 int __pow__ int?

How to fix mypy error, "Expression has type Any [misc]", for python type hinting of int __pow__ int?

我有一个 python 函数,它使用带有两个 int 的 python __pow__ (**) 运算符,Mypy 告诉我表达式 b ** e 的类型为“ Any”,其中 b 和 e 的类型为“int”。我试图用 int(b ** e) 将表达式转换为 int,但我仍然收到错误。如何正确键入提示此表达式?

此外,如果表达式 b ** e 确实 return 键入“Any”,您能解释一下原因吗?

错误:

temp.py:7: error: Expression has type "Any"  [misc]
        power: Callable[[int, int], int] = lambda b, e: b ** e
                                                        ^

temp.py

from functools import reduce
from typing import Callable, Dict


def factorization_product(fact: Dict[int, int]) -> int:
    '''returns the product which has the prime factorization of fact'''
    power: Callable[[int, int], int] = lambda b, e: b ** e # error on expression "b ** e"
    product: Callable[[int, int], int] = lambda x, y: x * y
    return reduce(product, [power(b, e) for b, e in fact.items()], 1)

编辑:

我意识到我可以使用内置的 pow 和 operator.mul 而不是 lambda,但我仍然遇到错误。

错误:

temp.py:8: error: Expression has type "Any"  [misc]
        return reduce(mul, [pow(b, e) for b, e in fact.items()], 1)
                            ^

已修订 temp.py

from functools import reduce
from operator import mul
from typing import Dict


def factorization_product(fact: Dict[int, int]) -> int:
    '''returns the product which has the prime factorization of fact'''
    return reduce(mul, [pow(b, e) for b, e in fact.items()], 1)

Also, if the expression b ** e really does return type "Any", can you explain why?

检查 typeshed 显示 int 仅针对数字平方的特殊情况(x 类型 Literal[2])返回。这是因为即使 beinte 也可能是负数,在这种情况下结果是 float。由于结果可以是 floatint,因此一般情况下 typeshedAny 是一致的。

我会说这是语言限制。理想情况下,我们可以对 x 的所有 non-negative 整数使用 @overload,但 Literal 仅支持特定值。

要在使用 --disallow-any-expr 的同时解决这个问题,请像这样使用 typing.cast

power: Callable[[int, int], int] = lambda b, e: typing.cast(int, b ** e)

运行 mypy --disallow-any-expr temp.py 现在 returns Success: no issues found in 1 source file.

但在你盲目添加 cast 之前,请考虑我提出的 e 为负的场景,如果你这样做 int 会导致类型检查成功但运行时失败-特定操作,结果为 factorization_product。您可能想在此处添加验证。例如,没有验证:

factorial_sized_lst = [0] * factorization_product({1: 2, 3: -4})
尽管 mypy 报告 type-check 成功,但

在 run-time 处失败且 can't multiply sequence by non-int of type 'float'