基于pylint插件的参数设置多个推断类型

2024-04-26 22:45:24 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个通过类变量实现一些类型检查的类。 然后,当类被实例化时,定义的变量成为类的必需参数,并且具有必需的类型。图案如下所示:

class MyClass(MagicBaseClass):
    arg1 = ArgumentObj(allowedTypes=(basestring, ))
    arg2 = ArgumentObj(allowedTypes=(list, tuple))

    def myMethod(self):
        print type(self.arg1) # a basestring
        print type(self.arg2) # a list

mc = MyClass(arg1='test', arg2=())
mc.myMethod()

派林不喜欢这样。它将arg1arg2视为ArgumentObj的实例。因此,我想编写一个插件来读取传递的类型,并将这些对象视为我的MagicBaseClass中这些类型的实例。你知道吗

因此,我已经能够找出如何为类转换挖掘到正确的节点,并且我可以访问我需要的所有数据,但是我真的不知道如何处理它。kicker是允许的多个类型。我现在找不到任何例子来处理这个问题,我能找到的文档基本上都是无用的。你知道吗

from astroid import MANAGER
from astroid import nodes, node_classes

def transform_myClass(node):
    for key, value in node.locals.items():
        val = value[0]
        try:
            s = val.statement().value
            if s.func.name != 'ArgumentObj':
                continue
        except AttributeError:
            continue

        for child in s.get_children():
            if not isinstance(child, node_classes.Keyword):
                continue
            if child.arg == 'allowedTypes':
                typeNames = child.value
                #### And here is where I have no idea what to do next ####

MANAGER.register_transform(nodes.ClassDef, transform_myClass)

Tags: 实例selfnodechild类型ifvaluemyclass
1条回答
网友
1楼 · 发布于 2024-04-26 22:45:24

Name个对象。这些基本上都是在对它们执行任何操作之前文件中的字符串。要得到它们可能是什么,你必须.infer()它们。这会将类似于文件“basestring”中的单词变成astroid类ish对象basestring(实际上,它返回一个生成器。。。但这里有宽泛的笔触)。你知道吗

然后,给定这些astroid类ish对象,必须将类“实例化”为astroid实例ish对象。你知道吗

最后(重要的部分),node.locals.items(){name: list of instance-ish objects}的字典。更新字典可以设置推断类型。你知道吗

所以我上面的代码会变成:

from astroid import MANAGER
from astroid import nodes, node_classes

def transform_myClass(node):
    updater = {}
    for key, value in node.locals.items():
        val = value[0]
        try:
            s = val.statement().value
            if s.func.name != 'ArgumentObj':
                continue
        except AttributeError:
            continue

        # Collect all the inferred types in this list
        typeList = []
        for child in s.get_children():
            if not isinstance(child, node_classes.Keyword):
                continue

            # What I needed to do was here:
            # Infer the child classes, and return the instantiated class
            if child.arg == 'allowedTypes':
                for tc in child.value.get_children():
                    for cls in tc.infer():
                        typeList.append(cls.instantiate_class())

        updater[key] = typeList

    # Finally, I needed to update the locals
    # which sets the inferred types of the class members
    node.locals.update(updater)

MANAGER.register_transform(nodes.ClassDef, transform_myClass)

相关问题 更多 >