Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(335)

Side by Side Diff: third_party/logilab/logilab/astroid/utils.py

Issue 1920403002: [content/test/gpu] Run pylint check of gpu tests in unittest instead of PRESUBMIT (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Update path to LICENSE.txt of logilab/README.chromium Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
3 #
4 # This file is part of astroid.
5 #
6 # astroid is free software: you can redistribute it and/or modify it
7 # under the terms of the GNU Lesser General Public License as published by the
8 # Free Software Foundation, either version 2.1 of the License, or (at your
9 # option) any later version.
10 #
11 # astroid is distributed in the hope that it will be useful, but
12 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
14 # for more details.
15 #
16 # You should have received a copy of the GNU Lesser General Public License along
17 # with astroid. If not, see <http://www.gnu.org/licenses/>.
18 """this module contains some utilities to navigate in the tree or to
19 extract information from it
20 """
21 from __future__ import print_function
22
23 __docformat__ = "restructuredtext en"
24
25 from astroid.exceptions import AstroidBuildingException
26 from astroid.builder import parse
27
28
29 class ASTWalker(object):
30 """a walker visiting a tree in preorder, calling on the handler:
31
32 * visit_<class name> on entering a node, where class name is the class of
33 the node in lower case
34
35 * leave_<class name> on leaving a node, where class name is the class of
36 the node in lower case
37 """
38
39 def __init__(self, handler):
40 self.handler = handler
41 self._cache = {}
42
43 def walk(self, node, _done=None):
44 """walk on the tree from <node>, getting callbacks from handler"""
45 if _done is None:
46 _done = set()
47 if node in _done:
48 raise AssertionError((id(node), node, node.parent))
49 _done.add(node)
50 self.visit(node)
51 for child_node in node.get_children():
52 self.handler.set_context(node, child_node)
53 assert child_node is not node
54 self.walk(child_node, _done)
55 self.leave(node)
56 assert node.parent is not node
57
58 def get_callbacks(self, node):
59 """get callbacks from handler for the visited node"""
60 klass = node.__class__
61 methods = self._cache.get(klass)
62 if methods is None:
63 handler = self.handler
64 kid = klass.__name__.lower()
65 e_method = getattr(handler, 'visit_%s' % kid,
66 getattr(handler, 'visit_default', None))
67 l_method = getattr(handler, 'leave_%s' % kid,
68 getattr(handler, 'leave_default', None))
69 self._cache[klass] = (e_method, l_method)
70 else:
71 e_method, l_method = methods
72 return e_method, l_method
73
74 def visit(self, node):
75 """walk on the tree from <node>, getting callbacks from handler"""
76 method = self.get_callbacks(node)[0]
77 if method is not None:
78 method(node)
79
80 def leave(self, node):
81 """walk on the tree from <node>, getting callbacks from handler"""
82 method = self.get_callbacks(node)[1]
83 if method is not None:
84 method(node)
85
86
87 class LocalsVisitor(ASTWalker):
88 """visit a project by traversing the locals dictionary"""
89 def __init__(self):
90 ASTWalker.__init__(self, self)
91 self._visited = {}
92
93 def visit(self, node):
94 """launch the visit starting from the given node"""
95 if node in self._visited:
96 return
97 self._visited[node] = 1 # FIXME: use set ?
98 methods = self.get_callbacks(node)
99 if methods[0] is not None:
100 methods[0](node)
101 if 'locals' in node.__dict__: # skip Instance and other proxy
102 for local_node in node.values():
103 self.visit(local_node)
104 if methods[1] is not None:
105 return methods[1](node)
106
107
108 def _check_children(node):
109 """a helper function to check children - parent relations"""
110 for child in node.get_children():
111 ok = False
112 if child is None:
113 print("Hm, child of %s is None" % node)
114 continue
115 if not hasattr(child, 'parent'):
116 print(" ERROR: %s has child %s %x with no parent" % (
117 node, child, id(child)))
118 elif not child.parent:
119 print(" ERROR: %s has child %s %x with parent %r" % (
120 node, child, id(child), child.parent))
121 elif child.parent is not node:
122 print(" ERROR: %s %x has child %s %x with wrong parent %s" % (
123 node, id(node), child, id(child), child.parent))
124 else:
125 ok = True
126 if not ok:
127 print("lines;", node.lineno, child.lineno)
128 print("of module", node.root(), node.root().name)
129 raise AstroidBuildingException
130 _check_children(child)
131
132
133 class TreeTester(object):
134 '''A helper class to see _ast tree and compare with astroid tree
135
136 indent: string for tree indent representation
137 lineno: bool to tell if we should print the line numbers
138
139 >>> tester = TreeTester('print')
140 >>> print tester.native_tree_repr()
141
142 <Module>
143 . body = [
144 . <Print>
145 . . nl = True
146 . ]
147 >>> print tester.astroid_tree_repr()
148 Module()
149 body = [
150 Print()
151 dest =
152 values = [
153 ]
154 ]
155 '''
156
157 indent = '. '
158 lineno = False
159
160 def __init__(self, sourcecode):
161 self._string = ''
162 self.sourcecode = sourcecode
163 self._ast_node = None
164 self.build_ast()
165
166 def build_ast(self):
167 """build the _ast tree from the source code"""
168 self._ast_node = parse(self.sourcecode)
169
170 def native_tree_repr(self, node=None, indent=''):
171 """get a nice representation of the _ast tree"""
172 self._string = ''
173 if node is None:
174 node = self._ast_node
175 self._native_repr_tree(node, indent)
176 return self._string
177
178
179 def _native_repr_tree(self, node, indent, _done=None):
180 """recursive method for the native tree representation"""
181 from _ast import Load as _Load, Store as _Store, Del as _Del
182 from _ast import AST as Node
183 if _done is None:
184 _done = set()
185 if node in _done:
186 self._string += '\nloop in tree: %r (%s)' % (
187 node, getattr(node, 'lineno', None))
188 return
189 _done.add(node)
190 self._string += '\n' + indent + '<%s>' % node.__class__.__name__
191 indent += self.indent
192 if not hasattr(node, '__dict__'):
193 self._string += '\n' + self.indent + " ** node has no __dict__ " + s tr(node)
194 return
195 node_dict = node.__dict__
196 if hasattr(node, '_attributes'):
197 for a in node._attributes:
198 attr = node_dict[a]
199 if attr is None:
200 continue
201 if a in ("lineno", "col_offset") and not self.lineno:
202 continue
203 self._string += '\n' + indent + a + " = " + repr(attr)
204 for field in node._fields or ():
205 attr = node_dict[field]
206 if attr is None:
207 continue
208 if isinstance(attr, list):
209 if not attr:
210 continue
211 self._string += '\n' + indent + field + ' = ['
212 for elt in attr:
213 self._native_repr_tree(elt, indent, _done)
214 self._string += '\n' + indent + ']'
215 continue
216 if isinstance(attr, (_Load, _Store, _Del)):
217 continue
218 if isinstance(attr, Node):
219 self._string += '\n' + indent + field + " = "
220 self._native_repr_tree(attr, indent, _done)
221 else:
222 self._string += '\n' + indent + field + " = " + repr(attr)
223
224
225 def build_astroid_tree(self):
226 """build astroid tree from the _ast tree
227 """
228 from astroid.builder import AstroidBuilder
229 tree = AstroidBuilder().string_build(self.sourcecode)
230 return tree
231
232 def astroid_tree_repr(self, ids=False):
233 """build the astroid tree and return a nice tree representation"""
234 mod = self.build_astroid_tree()
235 return mod.repr_tree(ids)
236
237
238 __all__ = ('LocalsVisitor', 'ASTWalker',)
239
OLDNEW
« no previous file with comments | « third_party/logilab/logilab/astroid/test_utils.py ('k') | third_party/logilab/logilab/common/LICENSE.txt » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698