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

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

Issue 719313003: Revert "pylint: upgrade to 1.3.1" (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: Created 6 years, 1 month 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
« no previous file with comments | « third_party/logilab/astroid/scoped_nodes.py ('k') | third_party/logilab/common/LICENSE.txt » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
22 __docformat__ = "restructuredtext en"
23
24 from astroid.exceptions import AstroidBuildingException
25 from astroid.builder import parse
26
27
28 class ASTWalker(object):
29 """a walker visiting a tree in preorder, calling on the handler:
30
31 * visit_<class name> on entering a node, where class name is the class of
32 the node in lower case
33
34 * leave_<class name> on leaving a node, where class name is the class of
35 the node in lower case
36 """
37
38 def __init__(self, handler):
39 self.handler = handler
40 self._cache = {}
41
42 def walk(self, node, _done=None):
43 """walk on the tree from <node>, getting callbacks from handler"""
44 if _done is None:
45 _done = set()
46 if node in _done:
47 raise AssertionError((id(node), node, node.parent))
48 _done.add(node)
49 self.visit(node)
50 for child_node in node.get_children():
51 self.handler.set_context(node, child_node)
52 assert child_node is not node
53 self.walk(child_node, _done)
54 self.leave(node)
55 assert node.parent is not node
56
57 def get_callbacks(self, node):
58 """get callbacks from handler for the visited node"""
59 klass = node.__class__
60 methods = self._cache.get(klass)
61 if methods is None:
62 handler = self.handler
63 kid = klass.__name__.lower()
64 e_method = getattr(handler, 'visit_%s' % kid,
65 getattr(handler, 'visit_default', None))
66 l_method = getattr(handler, 'leave_%s' % kid,
67 getattr(handler, 'leave_default', None))
68 self._cache[klass] = (e_method, l_method)
69 else:
70 e_method, l_method = methods
71 return e_method, l_method
72
73 def visit(self, node):
74 """walk on the tree from <node>, getting callbacks from handler"""
75 method = self.get_callbacks(node)[0]
76 if method is not None:
77 method(node)
78
79 def leave(self, node):
80 """walk on the tree from <node>, getting callbacks from handler"""
81 method = self.get_callbacks(node)[1]
82 if method is not None:
83 method(node)
84
85
86 class LocalsVisitor(ASTWalker):
87 """visit a project by traversing the locals dictionary"""
88 def __init__(self):
89 ASTWalker.__init__(self, self)
90 self._visited = {}
91
92 def visit(self, node):
93 """launch the visit starting from the given node"""
94 if node in self._visited:
95 return
96 self._visited[node] = 1 # FIXME: use set ?
97 methods = self.get_callbacks(node)
98 if methods[0] is not None:
99 methods[0](node)
100 if 'locals' in node.__dict__: # skip Instance and other proxy
101 for local_node in node.values():
102 self.visit(local_node)
103 if methods[1] is not None:
104 return methods[1](node)
105
106
107 def _check_children(node):
108 """a helper function to check children - parent relations"""
109 for child in node.get_children():
110 ok = False
111 if child is None:
112 print "Hm, child of %s is None" % node
113 continue
114 if not hasattr(child, 'parent'):
115 print " ERROR: %s has child %s %x with no parent" % (
116 node, child, id(child))
117 elif not child.parent:
118 print " ERROR: %s has child %s %x with parent %r" % (
119 node, child, id(child), child.parent)
120 elif child.parent is not node:
121 print " ERROR: %s %x has child %s %x with wrong parent %s" % (
122 node, id(node), child, id(child), child.parent)
123 else:
124 ok = True
125 if not ok:
126 print "lines;", node.lineno, child.lineno
127 print "of module", node.root(), node.root().name
128 raise AstroidBuildingException
129 _check_children(child)
130
131
132 class TreeTester(object):
133 '''A helper class to see _ast tree and compare with astroid tree
134
135 indent: string for tree indent representation
136 lineno: bool to tell if we should print the line numbers
137
138 >>> tester = TreeTester('print')
139 >>> print tester.native_tree_repr()
140
141 <Module>
142 . body = [
143 . <Print>
144 . . nl = True
145 . ]
146 >>> print tester.astroid_tree_repr()
147 Module()
148 body = [
149 Print()
150 dest =
151 values = [
152 ]
153 ]
154 '''
155
156 indent = '. '
157 lineno = False
158
159 def __init__(self, sourcecode):
160 self._string = ''
161 self.sourcecode = sourcecode
162 self._ast_node = None
163 self.build_ast()
164
165 def build_ast(self):
166 """build the _ast tree from the source code"""
167 self._ast_node = parse(self.sourcecode)
168
169 def native_tree_repr(self, node=None, indent=''):
170 """get a nice representation of the _ast tree"""
171 self._string = ''
172 if node is None:
173 node = self._ast_node
174 self._native_repr_tree(node, indent)
175 return self._string
176
177
178 def _native_repr_tree(self, node, indent, _done=None):
179 """recursive method for the native tree representation"""
180 from _ast import Load as _Load, Store as _Store, Del as _Del
181 from _ast import AST as Node
182 if _done is None:
183 _done = set()
184 if node in _done:
185 self._string += '\nloop in tree: %r (%s)' % (
186 node, getattr(node, 'lineno', None))
187 return
188 _done.add(node)
189 self._string += '\n' + indent + '<%s>' % node.__class__.__name__
190 indent += self.indent
191 if not hasattr(node, '__dict__'):
192 self._string += '\n' + self.indent + " ** node has no __dict__ " + s tr(node)
193 return
194 node_dict = node.__dict__
195 if hasattr(node, '_attributes'):
196 for a in node._attributes:
197 attr = node_dict[a]
198 if attr is None:
199 continue
200 if a in ("lineno", "col_offset") and not self.lineno:
201 continue
202 self._string += '\n' + indent + a + " = " + repr(attr)
203 for field in node._fields or ():
204 attr = node_dict[field]
205 if attr is None:
206 continue
207 if isinstance(attr, list):
208 if not attr:
209 continue
210 self._string += '\n' + indent + field + ' = ['
211 for elt in attr:
212 self._native_repr_tree(elt, indent, _done)
213 self._string += '\n' + indent + ']'
214 continue
215 if isinstance(attr, (_Load, _Store, _Del)):
216 continue
217 if isinstance(attr, Node):
218 self._string += '\n' + indent + field + " = "
219 self._native_repr_tree(attr, indent, _done)
220 else:
221 self._string += '\n' + indent + field + " = " + repr(attr)
222
223
224 def build_astroid_tree(self):
225 """build astroid tree from the _ast tree
226 """
227 from astroid.builder import AstroidBuilder
228 tree = AstroidBuilder().string_build(self.sourcecode)
229 return tree
230
231 def astroid_tree_repr(self, ids=False):
232 """build the astroid tree and return a nice tree representation"""
233 mod = self.build_astroid_tree()
234 return mod.repr_tree(ids)
235
236
237 __all__ = ('LocalsVisitor', 'ASTWalker',)
238
OLDNEW
« no previous file with comments | « third_party/logilab/astroid/scoped_nodes.py ('k') | third_party/logilab/common/LICENSE.txt » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698