blob: bfe346bba8e3d75217914f0a1b2930f6b85d8c65 [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__)
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300209 if not(node.body and isinstance(node.body[0], Expr)):
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +0300210 return None
211 node = node.body[0].value
212 if isinstance(node, Str):
213 text = node.s
214 elif isinstance(node, Constant) and isinstance(node.value, str):
215 text = node.value
216 else:
217 return None
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300218 if clean:
Victor Stinnerf2c1aa12016-01-26 00:40:57 +0100219 import inspect
220 text = inspect.cleandoc(text)
221 return text
Georg Brandl0c77a822008-06-10 16:37:50 +0000222
223
224def walk(node):
225 """
Georg Brandl619e7ba2011-01-09 07:38:51 +0000226 Recursively yield all descendant nodes in the tree starting at *node*
227 (including *node* itself), in no specified order. This is useful if you
228 only want to modify nodes in place and don't care about the context.
Georg Brandl0c77a822008-06-10 16:37:50 +0000229 """
230 from collections import deque
231 todo = deque([node])
232 while todo:
233 node = todo.popleft()
234 todo.extend(iter_child_nodes(node))
235 yield node
236
237
238class NodeVisitor(object):
239 """
240 A node visitor base class that walks the abstract syntax tree and calls a
241 visitor function for every node found. This function may return a value
242 which is forwarded by the `visit` method.
243
244 This class is meant to be subclassed, with the subclass adding visitor
245 methods.
246
247 Per default the visitor functions for the nodes are ``'visit_'`` +
248 class name of the node. So a `TryFinally` node visit function would
249 be `visit_TryFinally`. This behavior can be changed by overriding
250 the `visit` method. If no visitor function exists for a node
251 (return value `None`) the `generic_visit` visitor is used instead.
252
253 Don't use the `NodeVisitor` if you want to apply changes to nodes during
254 traversing. For this a special visitor exists (`NodeTransformer`) that
255 allows modifications.
256 """
257
258 def visit(self, node):
259 """Visit a node."""
260 method = 'visit_' + node.__class__.__name__
261 visitor = getattr(self, method, self.generic_visit)
262 return visitor(node)
263
264 def generic_visit(self, node):
265 """Called if no explicit visitor function exists for a node."""
266 for field, value in iter_fields(node):
267 if isinstance(value, list):
268 for item in value:
269 if isinstance(item, AST):
270 self.visit(item)
271 elif isinstance(value, AST):
272 self.visit(value)
273
274
275class NodeTransformer(NodeVisitor):
276 """
277 A :class:`NodeVisitor` subclass that walks the abstract syntax tree and
278 allows modification of nodes.
279
280 The `NodeTransformer` will walk the AST and use the return value of the
281 visitor methods to replace or remove the old node. If the return value of
282 the visitor method is ``None``, the node will be removed from its location,
283 otherwise it is replaced with the return value. The return value may be the
284 original node in which case no replacement takes place.
285
286 Here is an example transformer that rewrites all occurrences of name lookups
287 (``foo``) to ``data['foo']``::
288
289 class RewriteName(NodeTransformer):
290
291 def visit_Name(self, node):
292 return copy_location(Subscript(
293 value=Name(id='data', ctx=Load()),
294 slice=Index(value=Str(s=node.id)),
295 ctx=node.ctx
296 ), node)
297
298 Keep in mind that if the node you're operating on has child nodes you must
299 either transform the child nodes yourself or call the :meth:`generic_visit`
300 method for the node first.
301
302 For nodes that were part of a collection of statements (that applies to all
303 statement nodes), the visitor may also return a list of nodes rather than
304 just a single node.
305
306 Usually you use the transformer like this::
307
308 node = YourTransformer().visit(node)
309 """
310
311 def generic_visit(self, node):
312 for field, old_value in iter_fields(node):
Georg Brandl0c77a822008-06-10 16:37:50 +0000313 if isinstance(old_value, list):
314 new_values = []
315 for value in old_value:
316 if isinstance(value, AST):
317 value = self.visit(value)
318 if value is None:
319 continue
320 elif not isinstance(value, AST):
321 new_values.extend(value)
322 continue
323 new_values.append(value)
324 old_value[:] = new_values
325 elif isinstance(old_value, AST):
326 new_node = self.visit(old_value)
327 if new_node is None:
328 delattr(node, field)
329 else:
330 setattr(node, field, new_node)
331 return node