如何使用 mypy 注释具有额外属性的类型?

问题描述 投票:0回答:1

我有一个

ast.UnaryOp
对象,但我手动添加了
parent
属性(请参阅 answer)。如何在函数中注释它?

我目前只有:

def _get_sim206(node: ast.UnaryOp):
    if isinstance(node.parent, ast.If):
        return False
    return True

但是 mypy 抱怨(理所当然)

ast.UnaryOp
没有
parent
属性。

我怎样才能告诉mypy

node
不是
ast.UnaryOp
而是
ast.UnaryOp + parent attribute

我的尝试

我创建了自己的

UnaryOp
类,它具有父属性。我可以用它来进行类型转换:

class UnaryOp(ast.UnaryOp):
    def __init__(self, orig: ast.UnaryOp) -> None:
        self.op = orig.op
        self.operand = orig.operand
        self.lineno = orig.lineno
        self.col_offset = orig.col_offset
        self.parent: ast.Expr = orig.parent  # type: ignore

它的缺点是我需要在很多地方输入cast,这是我介绍的

Any
。我更愿意如果我可以在某个地方声明该文件中的所有
ast.*
类型确实具有
parent
属性

python mypy python-typing
1个回答
1
投票

作为一种解决方法,您可以将

isinstance()
protocol 一起使用,并用 @runtime_checkable 装饰,这将在运行时检查所有协议成员是否已定义,并确保静态正确性。

from typing import Protocol, runtime_checkable, cast
import ast


@runtime_checkable
class ParentProto(Protocol):
    parent: ast.AST
    

def foo(node: ast.UnaryOp):
    if isinstance(node, ParentProto):
        # use node.parent
        p = node.parent
        l = node.lineno
# assignment
g = ast.UnaryOp()
cast(ParentProto, g).parent = ast.If()
© www.soinside.com 2019 - 2024. All rights reserved.