如何让pylint通过astroid识别变量
How to make pylint recognize variable via astroid
我正在尝试"teach" pylint 来识别成员函数,我的场景可以简化为以下:
主模块:a.py
from plugins import plu
class FooClass(object):
def bar(self):
self.plu.foo("asdasd")
if __name__ == '__main__':
a = FooClass()
for plugin_name, plugin in plu.plugins.items():
setattr(a, plugin_name, plugin())
a.bar()
插件文件夹文件plu.py:
plugins = {}
class Plugin(object):
def foo(self, arg):
print("bar %s" % arg)
plugins['plu'] = Plugin
插件在 FooClass
对象上注册自己和一些其他方法 "introduces" 的想法。
a.py 的输出是:
bar asdasd
(符合预期)
运行 pylint -E a.py
产生以下错误:
pylint -E a.py
************* Module a
E: 5, 8: Instance of 'FooClass' has no 'plu' member (no-member)
我曾尝试编写以下 pylint 插件:
import astroid
from astroid import nodes
def transform_test_class(mod):
if mod.name != 'a':
return
foo_cls = mod.lookup('FooClass')[1]
plugin_cls_def = astroid.MANAGER.ast_from_module_name('plugins.plu')
foo_cls[0].locals['plu'] = plugin_cls_def.lookup('Plugin')[1]
def register(linter):
astroid.MANAGER.register_transform(nodes.Module, transform_test_class)
运行pylint --load-plugins=$(pwd)/pylint-plugin -E a.py
的输出是:
************* Module a
E: 5, 8: No value for argument 'arg' in unbound method call (no-value-for-parameter)
从错误中我怀疑我以某种方式错误地引入了 属性,因为 pylint 认为方法 foo
是无界的,但它确实是有界的。我需要找到一种方法来告诉 pylint foo_cls[0].locals['plu']
实际上是 class Plugin
的一个实例,而不是 class 本身。知道如何实现吗?
您需要在将插件添加到 FooClass 的局部变量时实例化插件 class。所以将这一行 foo_cls[0].locals['plu'] = plugin_cls_def.lookup('Plugin')[1]
替换为 foo_cls[0].locals['plu'] = [cls.instantiate_class() for cls in plugin_cls_def.lookup('Plugin')[1]]
我正在尝试"teach" pylint 来识别成员函数,我的场景可以简化为以下:
主模块:a.py
from plugins import plu
class FooClass(object):
def bar(self):
self.plu.foo("asdasd")
if __name__ == '__main__':
a = FooClass()
for plugin_name, plugin in plu.plugins.items():
setattr(a, plugin_name, plugin())
a.bar()
插件文件夹文件plu.py:
plugins = {}
class Plugin(object):
def foo(self, arg):
print("bar %s" % arg)
plugins['plu'] = Plugin
插件在 FooClass
对象上注册自己和一些其他方法 "introduces" 的想法。
a.py 的输出是:
bar asdasd
(符合预期)
运行 pylint -E a.py
产生以下错误:
pylint -E a.py
************* Module a
E: 5, 8: Instance of 'FooClass' has no 'plu' member (no-member)
我曾尝试编写以下 pylint 插件:
import astroid
from astroid import nodes
def transform_test_class(mod):
if mod.name != 'a':
return
foo_cls = mod.lookup('FooClass')[1]
plugin_cls_def = astroid.MANAGER.ast_from_module_name('plugins.plu')
foo_cls[0].locals['plu'] = plugin_cls_def.lookup('Plugin')[1]
def register(linter):
astroid.MANAGER.register_transform(nodes.Module, transform_test_class)
运行pylint --load-plugins=$(pwd)/pylint-plugin -E a.py
的输出是:
************* Module a
E: 5, 8: No value for argument 'arg' in unbound method call (no-value-for-parameter)
从错误中我怀疑我以某种方式错误地引入了 属性,因为 pylint 认为方法 foo
是无界的,但它确实是有界的。我需要找到一种方法来告诉 pylint foo_cls[0].locals['plu']
实际上是 class Plugin
的一个实例,而不是 class 本身。知道如何实现吗?
您需要在将插件添加到 FooClass 的局部变量时实例化插件 class。所以将这一行 foo_cls[0].locals['plu'] = plugin_cls_def.lookup('Plugin')[1]
替换为 foo_cls[0].locals['plu'] = [cls.instantiate_class() for cls in plugin_cls_def.lookup('Plugin')[1]]