预期类型 'Type[Add | Sub | Mult | Div | Pow | BitXor | USub]',却得到了 'Type[operator]'

Expected type 'Type[Add | Sub | Mult | Div | Pow | BitXor | USub]', got 'Type[operator]' instead

我使用 nifty class that evaluates string expressionsand converts them to their math equivalent :

# Taken out of context for MVCE

import ast
import operator as op

OPERATORS = {
    ast.Add: op.add,
    ast.Sub: op.sub,
    ast.Mult: op.mul,
    ast.Div: op.truediv,
    ast.Pow: op.pow,
    ast.BitXor: op.xor,
    ast.USub: op.neg
}

def eval_expr(expr):

    return eval_(ast.parse(expr, mode='eval').body)

def eval_(node):
    if isinstance(node, ast.Num):  # <number>
        value = node.n
    elif isinstance(node, ast.BinOp):  # <left> <operator> <right>
        value = OPERATORS[type(node.op)](eval_(node.left), eval_(node.right))
    elif isinstance(node, ast.UnaryOp):  # <operator> <operand> e.g., -1
        value = OPERATORS[type(node.op)](eval_(node.operand))
    else:
        raise TypeError(node)

    return value

x = eval_expr("1 + 2")
print(x)

PyCharm 代码检查将 type(node.op) 的实例突出显示为有问题的:

Expected type 'Type[Add | Sub | Mult | Div | Pow | BitXor | USub]' (matched generic type '_KT'), got 'Type[operator]' instead
Expected type 'Type[Add | Sub | Mult | Div | Pow | BitXor | USub]' (matched generic type '_KT'), got 'Type[unaryop]' instead

class 似乎运行良好,但我的强迫症想知道如何重构它以避免检查警告。或者这是一个 PyCharm 检查 gremlin?

类型检查器警告您,将运算符的 AST 节点类型映射到它们的实现的字典不完整。类型检查器知道 node.op 的所有可能类型(它似乎被描述为 ast.operatorast.unaryop 父类型的子类型),并且注意到你的字典没有处理所有这些。

由于有些运算符您没有包含,因此可解析表达式(例如,"2 << 5" 执行左移,或 "~31" 执行按位反转)是可能的您的代码无法处理。

虽然我不使用 PyCharm 因此无法自己测试它,但您可以通过在代码中添加一些错误处理来满足其类型检查器的要求,这样您就不会输入运算符支持仍将得到适当处理,而不是导致未捕获的异常(例如字典中的 KeyError)泄漏出去。例如,您可以使用 OPERATORS.get(type(node.op)),然后在调用结果之前测试 None。如果运算符类型不在字典中,您将引发自己的异常。