blob: 2ecb03f38bc0d00e31f57fed95947517676d8b95 [file] [log] [blame]
Georg Brandl0c77a822008-06-10 16:37:50 +00001"""
2 ast
3 ~~~
4
5 The `ast` module helps Python applications to process trees of the Python
6 abstract syntax grammar. The abstract syntax itself might change with
7 each Python release; this module helps to find out programmatically what
8 the current grammar looks like and allows modifications of it.
9
10 An abstract syntax tree can be generated by passing `ast.PyCF_ONLY_AST` as
11 a flag to the `compile()` builtin function or by using the `parse()`
12 function from this module. The result will be a tree of objects whose
13 classes all inherit from `ast.AST`.
14
15 A modified abstract syntax tree can be compiled into a Python code object
16 using the built-in `compile()` function.
17
18 Additionally various helper functions are provided that make working with
19 the trees simpler. The main intention of the helper functions and this
20 module in general is to provide an easy to use interface for libraries
21 that work tightly with the python syntax (template engines for example).
22
23
24 :copyright: Copyright 2008 by Armin Ronacher.
25 :license: Python License.
26"""
27from _ast import *
28
29
Terry Reedyfeac6242011-01-24 21:36:03 +000030def parse(source, filename='<unknown>', mode='exec'):
Georg Brandl0c77a822008-06-10 16:37:50 +000031 """
Terry Reedyfeac6242011-01-24 21:36:03 +000032 Parse the source into an AST node.
33 Equivalent to compile(source, filename, mode, PyCF_ONLY_AST).
Georg Brandl0c77a822008-06-10 16:37:50 +000034 """
Terry Reedyfeac6242011-01-24 21:36:03 +000035 return compile(source, filename, mode, PyCF_ONLY_AST)
Georg Brandl0c77a822008-06-10 16:37:50 +000036
37
38def literal_eval(node_or_string):
39 """
40 Safely evaluate an expression node or a string containing a Python
41 expression. The string or node provided may only consist of the following
Éric Araujo2a83cc62011-04-17 19:10:27 +020042 Python literal structures: strings, bytes, numbers, tuples, lists, dicts,
43 sets, booleans, and None.
Georg Brandl0c77a822008-06-10 16:37:50 +000044 """
Georg Brandl0c77a822008-06-10 16:37:50 +000045 if isinstance(node_or_string, str):
46 node_or_string = parse(node_or_string, mode='eval')
47 if isinstance(node_or_string, Expression):
48 node_or_string = node_or_string.body
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +020049 def _convert_num(node):
50 if isinstance(node, Constant):
51 if isinstance(node.value, (int, float, complex)):
52 return node.value
53 elif isinstance(node, Num):
54 return node.n
55 raise ValueError('malformed node or string: ' + repr(node))
56 def _convert_signed_num(node):
57 if isinstance(node, UnaryOp) and isinstance(node.op, (UAdd, USub)):
58 operand = _convert_num(node.operand)
59 if isinstance(node.op, UAdd):
60 return + operand
61 else:
62 return - operand
63 return _convert_num(node)
Georg Brandl0c77a822008-06-10 16:37:50 +000064 def _convert(node):
Victor Stinnerf2c1aa12016-01-26 00:40:57 +010065 if isinstance(node, Constant):
66 return node.value
67 elif isinstance(node, (Str, Bytes)):
Georg Brandl0c77a822008-06-10 16:37:50 +000068 return node.s
69 elif isinstance(node, Num):
70 return node.n
71 elif isinstance(node, Tuple):
72 return tuple(map(_convert, node.elts))
73 elif isinstance(node, List):
74 return list(map(_convert, node.elts))
Georg Brandl492f3fc2010-07-11 09:41:21 +000075 elif isinstance(node, Set):
76 return set(map(_convert, node.elts))
Georg Brandl0c77a822008-06-10 16:37:50 +000077 elif isinstance(node, Dict):
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +020078 return dict(zip(map(_convert, node.keys),
79 map(_convert, node.values)))
Benjamin Peterson442f2092012-12-06 17:41:04 -050080 elif isinstance(node, NameConstant):
81 return node.value
Victor Stinnerf2c1aa12016-01-26 00:40:57 +010082 elif isinstance(node, BinOp) and isinstance(node.op, (Add, Sub)):
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +020083 left = _convert_signed_num(node.left)
84 right = _convert_num(node.right)
85 if isinstance(left, (int, float)) and isinstance(right, complex):
Victor Stinnerf2c1aa12016-01-26 00:40:57 +010086 if isinstance(node.op, Add):
87 return left + right
88 else:
89 return left - right
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +020090 return _convert_signed_num(node)
Georg Brandl0c77a822008-06-10 16:37:50 +000091 return _convert(node_or_string)
92
93
94def dump(node, annotate_fields=True, include_attributes=False):
95 """
96 Return a formatted dump of the tree in *node*. This is mainly useful for
97 debugging purposes. The returned string will show the names and the values
98 for fields. This makes the code impossible to evaluate, so if evaluation is
99 wanted *annotate_fields* must be set to False. Attributes such as line
Benjamin Petersondcf97b92008-07-02 17:30:14 +0000100 numbers and column offsets are not dumped by default. If this is wanted,
Georg Brandl0c77a822008-06-10 16:37:50 +0000101 *include_attributes* can be set to True.
102 """
103 def _format(node):
104 if isinstance(node, AST):
105 fields = [(a, _format(b)) for a, b in iter_fields(node)]
106 rv = '%s(%s' % (node.__class__.__name__, ', '.join(
107 ('%s=%s' % field for field in fields)
108 if annotate_fields else
109 (b for a, b in fields)
110 ))
111 if include_attributes and node._attributes:
112 rv += fields and ', ' or ' '
113 rv += ', '.join('%s=%s' % (a, _format(getattr(node, a)))
114 for a in node._attributes)
115 return rv + ')'
116 elif isinstance(node, list):
117 return '[%s]' % ', '.join(_format(x) for x in node)
118 return repr(node)
119 if not isinstance(node, AST):
120 raise TypeError('expected AST, got %r' % node.__class__.__name__)
121 return _format(node)
122
123
124def copy_location(new_node, old_node):
125 """
126 Copy source location (`lineno` and `col_offset` attributes) from
127 *old_node* to *new_node* if possible, and return *new_node*.
128 """
129 for attr in 'lineno', 'col_offset':
130 if attr in old_node._attributes and attr in new_node._attributes \
131 and hasattr(old_node, attr):
132 setattr(new_node, attr, getattr(old_node, attr))
133 return new_node
134
135
136def fix_missing_locations(node):
137 """
138 When you compile a node tree with compile(), the compiler expects lineno and
139 col_offset attributes for every node that supports them. This is rather
140 tedious to fill in for generated nodes, so this helper adds these attributes
141 recursively where not already set, by setting them to the values of the
142 parent node. It works recursively starting at *node*.
143 """
144 def _fix(node, lineno, col_offset):
145 if 'lineno' in node._attributes:
146 if not hasattr(node, 'lineno'):
147 node.lineno = lineno
148 else:
149 lineno = node.lineno
150 if 'col_offset' in node._attributes:
151 if not hasattr(node, 'col_offset'):
152 node.col_offset = col_offset
153 else:
154 col_offset = node.col_offset
155 for child in iter_child_nodes(node):
156 _fix(child, lineno, col_offset)
157 _fix(node, 1, 0)
158 return node
159
160
161def increment_lineno(node, n=1):
162 """
163 Increment the line number of each node in the tree starting at *node* by *n*.
164 This is useful to "move code" to a different location in a file.
165 """
Georg Brandl0c77a822008-06-10 16:37:50 +0000166 for child in walk(node):
167 if 'lineno' in child._attributes:
168 child.lineno = getattr(child, 'lineno', 0) + n
169 return node
170
171
172def iter_fields(node):
173 """
174 Yield a tuple of ``(fieldname, value)`` for each field in ``node._fields``
175 that is present on *node*.
176 """
177 for field in node._fields:
178 try:
179 yield field, getattr(node, field)
180 except AttributeError:
181 pass
182
183
184def iter_child_nodes(node):
185 """
186 Yield all direct child nodes of *node*, that is, all fields that are nodes
187 and all items of fields that are lists of nodes.
188 """
189 for name, field in iter_fields(node):
190 if isinstance(field, AST):
191 yield field
192 elif isinstance(field, list):
193 for item in field:
194 if isinstance(item, AST):
195 yield item
196
197
198def get_docstring(node, clean=True):
199 """
200 Return the docstring for the given node or None if no docstring can
201 be found. If the node provided does not have docstrings a TypeError
202 will be raised.
Matthias Bussonnier41cea702017-02-23 22:44:19 -0800203
204 If *clean* is `True`, all tabs are expanded to spaces and any whitespace
205 that can be uniformly removed from the second line onwards is removed.
Georg Brandl0c77a822008-06-10 16:37:50 +0000206 """
Yury Selivanov2f07a662015-07-23 08:54:35 +0300207 if not isinstance(node, (AsyncFunctionDef, FunctionDef, ClassDef, Module)):
Georg Brandl0c77a822008-06-10 16:37:50 +0000208 raise TypeError("%r can't have docstrings" % node.__class__.__name__)
INADA Naokicb41b272017-02-23 00:31:59 +0900209 text = node.docstring
Matthias Bussonnier41cea702017-02-23 22:44:19 -0800210 if clean and text:
Victor Stinnerf2c1aa12016-01-26 00:40:57 +0100211 import inspect
212 text = inspect.cleandoc(text)
213 return text
Georg Brandl0c77a822008-06-10 16:37:50 +0000214
215
216def walk(node):
217 """
Georg Brandl619e7ba2011-01-09 07:38:51 +0000218 Recursively yield all descendant nodes in the tree starting at *node*
219 (including *node* itself), in no specified order. This is useful if you
220 only want to modify nodes in place and don't care about the context.
Georg Brandl0c77a822008-06-10 16:37:50 +0000221 """
222 from collections import deque
223 todo = deque([node])
224 while todo:
225 node = todo.popleft()
226 todo.extend(iter_child_nodes(node))
227 yield node
228
229
230class NodeVisitor(object):
231 """
232 A node visitor base class that walks the abstract syntax tree and calls a
233 visitor function for every node found. This function may return a value
234 which is forwarded by the `visit` method.
235
236 This class is meant to be subclassed, with the subclass adding visitor
237 methods.
238
239 Per default the visitor functions for the nodes are ``'visit_'`` +
240 class name of the node. So a `TryFinally` node visit function would
241 be `visit_TryFinally`. This behavior can be changed by overriding
242 the `visit` method. If no visitor function exists for a node
243 (return value `None`) the `generic_visit` visitor is used instead.
244
245 Don't use the `NodeVisitor` if you want to apply changes to nodes during
246 traversing. For this a special visitor exists (`NodeTransformer`) that
247 allows modifications.
248 """
249
250 def visit(self, node):
251 """Visit a node."""
252 method = 'visit_' + node.__class__.__name__
253 visitor = getattr(self, method, self.generic_visit)
254 return visitor(node)
255
256 def generic_visit(self, node):
257 """Called if no explicit visitor function exists for a node."""
258 for field, value in iter_fields(node):
259 if isinstance(value, list):
260 for item in value:
261 if isinstance(item, AST):
262 self.visit(item)
263 elif isinstance(value, AST):
264 self.visit(value)
265
266
267class NodeTransformer(NodeVisitor):
268 """
269 A :class:`NodeVisitor` subclass that walks the abstract syntax tree and
270 allows modification of nodes.
271
272 The `NodeTransformer` will walk the AST and use the return value of the
273 visitor methods to replace or remove the old node. If the return value of
274 the visitor method is ``None``, the node will be removed from its location,
275 otherwise it is replaced with the return value. The return value may be the
276 original node in which case no replacement takes place.
277
278 Here is an example transformer that rewrites all occurrences of name lookups
279 (``foo``) to ``data['foo']``::
280
281 class RewriteName(NodeTransformer):
282
283 def visit_Name(self, node):
284 return copy_location(Subscript(
285 value=Name(id='data', ctx=Load()),
286 slice=Index(value=Str(s=node.id)),
287 ctx=node.ctx
288 ), node)
289
290 Keep in mind that if the node you're operating on has child nodes you must
291 either transform the child nodes yourself or call the :meth:`generic_visit`
292 method for the node first.
293
294 For nodes that were part of a collection of statements (that applies to all
295 statement nodes), the visitor may also return a list of nodes rather than
296 just a single node.
297
298 Usually you use the transformer like this::
299
300 node = YourTransformer().visit(node)
301 """
302
303 def generic_visit(self, node):
304 for field, old_value in iter_fields(node):
Georg Brandl0c77a822008-06-10 16:37:50 +0000305 if isinstance(old_value, list):
306 new_values = []
307 for value in old_value:
308 if isinstance(value, AST):
309 value = self.visit(value)
310 if value is None:
311 continue
312 elif not isinstance(value, AST):
313 new_values.extend(value)
314 continue
315 new_values.append(value)
316 old_value[:] = new_values
317 elif isinstance(old_value, AST):
318 new_node = self.visit(old_value)
319 if new_node is None:
320 delattr(node, field)
321 else:
322 setattr(node, field, new_node)
323 return node