2016-07-10 14 views
1

Ich versuche zu „lehren“ Pylint Memberfunktion zu erkennen, kann mein Szenario der folgenden vereinfacht werden:Wie man Pylint Variable erkennen über astroid

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

Plugins-Ordner-Datei plu.py:

plugins = {} 
class Plugin(object): 
    def foo(self, arg): 
     print("bar %s" % arg) 

plugins['plu'] = Plugin 

die Idee, dass Plugins registrieren sich selbst und einige andere Verfahren „einleitet“, um sie auf dem FooClass Objekt.

Ausgabe des a.py ist:

bar asdasd 

(wie erwartet)

pylint -E a.py Lauf ergibt die folgende Fehlermeldung:

pylint -E a.py 
************* Module a 
E: 5, 8: Instance of 'FooClass' has no 'plu' member (no-member) 

ich versucht hatte, die folgende pylint- zu schreiben plugin:

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) 

Output pylint --load-plugins=$(pwd)/pylint-plugin -E a.py laufen ist:

************* Module a 
E: 5, 8: No value for argument 'arg' in unbound method call (no-value-for-parameter) 

Aus dem Fehler Ich vermute, dass ich irgendwie die Eigenschaft falsch vorstellen, wie Pylint denkt, dass Verfahren foo unbeschränkt ist, aber es ist in der Tat begrenzt. Ich muss einen Weg finden, pylint zu sagen, dass foo_cls[0].locals['plu'] ist eigentlich eine Instanz der Klasse Plugin und nicht die Klasse selbst. Irgendeine Idee, wie das erreicht werden kann?

Antwort

2

Sie müssen die Plugin-Klasse instanziieren, wenn Sie sie den Locals der FooClass hinzufügen. Ersetzen Sie also diese Zeile foo_cls[0].locals['plu'] = plugin_cls_def.lookup('Plugin')[1] durch foo_cls[0].locals['plu'] = [cls.instantiate_class() for cls in plugin_cls_def.lookup('Plugin')[1]]