如何使用 mypy 注释具有额外属性的类型? [英] How do I annotate a type which has an extra attribute with mypy?

查看:56
本文介绍了如何使用 mypy 注释具有额外属性的类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 ast.UnaryOp 对象,但我手动添加了一个 parent 属性(请参阅 答案).如何在函数中对此进行注释?

I have an ast.UnaryOp object, but I manually added a parent attribute (see answer). How do I annotate this in a function?

我目前只有:

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

但是 mypy 抱怨(理所当然)ast.UnaryOp 没有 parent 属性.

But mypy complains (rightfully so) that ast.UnaryOp does not have the parent attribute.

如何告诉 mypy node 不是 ast.UnaryOp 而是 ast.UnaryOp + parent 属性?

How can I tell mypy that the node is not ast.UnaryOp but ast.UnaryOp + parent attribute?

我创建了自己的 UnaryOp 类,它有一个父属性.我可以用它来进行类型转换:

I've created my own UnaryOp class which has a parent attribute. I can use this for type-casting:

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

它的缺点是我需要在很多地方输入类型转换并且我引入了Any.我希望我能在某处声明该文件中的所有 ast.* 类型确实具有 parent 属性

The downside of it is that I need to type cast in a lot of places and that I introduced Any. I would prefer if I could just state somewhere that all ast.* types in that file do have a parent attribute

推荐答案

作为一种解决方法,您可以使用 isinstance()protocol 装饰有 @runtime_checkable,它将在运行时检查所有协议成员是否已定义,并确保静态正确性.

As a workaround you could use isinstance() with protocol decorated with the @runtime_checkable, that will check at runtime that all protocol members are defined and also ensure statical correctness.

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()

这篇关于如何使用 mypy 注释具有额外属性的类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆