1 """https://pastebin.logilab.fr/show/860/""" |
|
2 |
|
3 from astroid import MANAGER, InferenceError, nodes, scoped_nodes |
|
4 from astroid.builder import AstroidBuilder |
|
5 |
|
6 def turn_function_to_class(node): |
|
7 """turn a Function node into a Class node (in-place)""" |
|
8 node.__class__ = scoped_nodes.Class |
|
9 node.bases = () |
|
10 # remove return nodes so that we don't get warned about 'return outside |
|
11 # function' by pylint |
|
12 for rnode in node.nodes_of_class(nodes.Return): |
|
13 rnode.parent.body.remove(rnode) |
|
14 # that seems to be enough :) |
|
15 |
|
16 |
|
17 def cubicweb_transform(module): |
|
18 # handle objectify_predicate decorator (and its former name until bw compat |
|
19 # is kept). Only look at module level functions, should be enough. |
|
20 for assnodes in module.locals.values(): |
|
21 for node in assnodes: |
|
22 if isinstance(node, scoped_nodes.Function) and node.decorators: |
|
23 for decorator in node.decorators.nodes: |
|
24 try: |
|
25 for infered in decorator.infer(): |
|
26 if infered.name in ('objectify_predicate', 'objectify_selector'): |
|
27 turn_function_to_class(node) |
|
28 break |
|
29 else: |
|
30 continue |
|
31 break |
|
32 except InferenceError: |
|
33 continue |
|
34 # add yams base types into 'yams.buildobjs', astng doesn't grasp globals() |
|
35 # magic in there |
|
36 if module.name == 'yams.buildobjs': |
|
37 from yams import BASE_TYPES |
|
38 for etype in BASE_TYPES: |
|
39 module.locals[etype] = [scoped_nodes.Class(etype, None)] |
|
40 # add data() to uiprops module |
|
41 if module.name.split('.')[-1] == 'uiprops': |
|
42 fake = AstroidBuilder(MANAGER).string_build(''' |
|
43 def data(string): |
|
44 return u'' |
|
45 ''') |
|
46 module.locals['data'] = fake.locals['data'] |
|
47 |
|
48 def register(linter): |
|
49 """called when loaded by pylint --load-plugins, nothing to do here""" |
|
50 MANAGER.register_transform(nodes.Module, cubicweb_transform) |
|