blob: 6c1e978b0586677868f913a96157db3188968d17 [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):
Serhiy Storchaka3f228112018-09-27 17:42:37 +030051 if type(node.value) in (int, float, complex):
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +020052 return node.value
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +020053 raise ValueError('malformed node or string: ' + repr(node))
54 def _convert_signed_num(node):
55 if isinstance(node, UnaryOp) and isinstance(node.op, (UAdd, USub)):
56 operand = _convert_num(node.operand)
57 if isinstance(node.op, UAdd):
58 return + operand
59 else:
60 return - operand
61 return _convert_num(node)
Georg Brandl0c77a822008-06-10 16:37:50 +000062 def _convert(node):
Victor Stinnerf2c1aa12016-01-26 00:40:57 +010063 if isinstance(node, Constant):
64 return node.value
Georg Brandl0c77a822008-06-10 16:37:50 +000065 elif isinstance(node, Tuple):
66 return tuple(map(_convert, node.elts))
67 elif isinstance(node, List):
68 return list(map(_convert, node.elts))
Georg Brandl492f3fc2010-07-11 09:41:21 +000069 elif isinstance(node, Set):
70 return set(map(_convert, node.elts))
Georg Brandl0c77a822008-06-10 16:37:50 +000071 elif isinstance(node, Dict):
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +020072 return dict(zip(map(_convert, node.keys),
73 map(_convert, node.values)))
Victor Stinnerf2c1aa12016-01-26 00:40:57 +010074 elif isinstance(node, BinOp) and isinstance(node.op, (Add, Sub)):
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +020075 left = _convert_signed_num(node.left)
76 right = _convert_num(node.right)
77 if isinstance(left, (int, float)) and isinstance(right, complex):
Victor Stinnerf2c1aa12016-01-26 00:40:57 +010078 if isinstance(node.op, Add):
79 return left + right
80 else:
81 return left - right
Serhiy Storchakad8ac4d12018-01-04 11:15:39 +020082 return _convert_signed_num(node)
Georg Brandl0c77a822008-06-10 16:37:50 +000083 return _convert(node_or_string)
84
85
86def dump(node, annotate_fields=True, include_attributes=False):
87 """
88 Return a formatted dump of the tree in *node*. This is mainly useful for
89 debugging purposes. The returned string will show the names and the values
90 for fields. This makes the code impossible to evaluate, so if evaluation is
91 wanted *annotate_fields* must be set to False. Attributes such as line
Benjamin Petersondcf97b92008-07-02 17:30:14 +000092 numbers and column offsets are not dumped by default. If this is wanted,
Georg Brandl0c77a822008-06-10 16:37:50 +000093 *include_attributes* can be set to True.
94 """
95 def _format(node):
96 if isinstance(node, AST):
97 fields = [(a, _format(b)) for a, b in iter_fields(node)]
98 rv = '%s(%s' % (node.__class__.__name__, ', '.join(
99 ('%s=%s' % field for field in fields)
100 if annotate_fields else
101 (b for a, b in fields)
102 ))
103 if include_attributes and node._attributes:
104 rv += fields and ', ' or ' '
105 rv += ', '.join('%s=%s' % (a, _format(getattr(node, a)))
106 for a in node._attributes)
107 return rv + ')'
108 elif isinstance(node, list):
109 return '[%s]' % ', '.join(_format(x) for x in node)
110 return repr(node)
111 if not isinstance(node, AST):
112 raise TypeError('expected AST, got %r' % node.__class__.__name__)
113 return _format(node)
114
115
116def copy_location(new_node, old_node):
117 """
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000118 Copy source location (`lineno`, `col_offset`, `end_lineno`, and `end_col_offset`
119 attributes) from *old_node* to *new_node* if possible, and return *new_node*.
Georg Brandl0c77a822008-06-10 16:37:50 +0000120 """
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000121 for attr in 'lineno', 'col_offset', 'end_lineno', 'end_col_offset':
Georg Brandl0c77a822008-06-10 16:37:50 +0000122 if attr in old_node._attributes and attr in new_node._attributes \
123 and hasattr(old_node, attr):
124 setattr(new_node, attr, getattr(old_node, attr))
125 return new_node
126
127
128def fix_missing_locations(node):
129 """
130 When you compile a node tree with compile(), the compiler expects lineno and
131 col_offset attributes for every node that supports them. This is rather
132 tedious to fill in for generated nodes, so this helper adds these attributes
133 recursively where not already set, by setting them to the values of the
134 parent node. It works recursively starting at *node*.
135 """
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000136 def _fix(node, lineno, col_offset, end_lineno, end_col_offset):
Georg Brandl0c77a822008-06-10 16:37:50 +0000137 if 'lineno' in node._attributes:
138 if not hasattr(node, 'lineno'):
139 node.lineno = lineno
140 else:
141 lineno = node.lineno
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000142 if 'end_lineno' in node._attributes:
143 if not hasattr(node, 'end_lineno'):
144 node.end_lineno = end_lineno
145 else:
146 end_lineno = node.end_lineno
Georg Brandl0c77a822008-06-10 16:37:50 +0000147 if 'col_offset' in node._attributes:
148 if not hasattr(node, 'col_offset'):
149 node.col_offset = col_offset
150 else:
151 col_offset = node.col_offset
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000152 if 'end_col_offset' in node._attributes:
153 if not hasattr(node, 'end_col_offset'):
154 node.end_col_offset = end_col_offset
155 else:
156 end_col_offset = node.end_col_offset
Georg Brandl0c77a822008-06-10 16:37:50 +0000157 for child in iter_child_nodes(node):
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000158 _fix(child, lineno, col_offset, end_lineno, end_col_offset)
159 _fix(node, 1, 0, 1, 0)
Georg Brandl0c77a822008-06-10 16:37:50 +0000160 return node
161
162
163def increment_lineno(node, n=1):
164 """
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000165 Increment the line number and end line number of each node in the tree
166 starting at *node* by *n*. This is useful to "move code" to a different
167 location in a file.
Georg Brandl0c77a822008-06-10 16:37:50 +0000168 """
Georg Brandl0c77a822008-06-10 16:37:50 +0000169 for child in walk(node):
170 if 'lineno' in child._attributes:
171 child.lineno = getattr(child, 'lineno', 0) + n
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000172 if 'end_lineno' in child._attributes:
173 child.end_lineno = getattr(child, 'end_lineno', 0) + n
Georg Brandl0c77a822008-06-10 16:37:50 +0000174 return node
175
176
177def iter_fields(node):
178 """
179 Yield a tuple of ``(fieldname, value)`` for each field in ``node._fields``
180 that is present on *node*.
181 """
182 for field in node._fields:
183 try:
184 yield field, getattr(node, field)
185 except AttributeError:
186 pass
187
188
189def iter_child_nodes(node):
190 """
191 Yield all direct child nodes of *node*, that is, all fields that are nodes
192 and all items of fields that are lists of nodes.
193 """
194 for name, field in iter_fields(node):
195 if isinstance(field, AST):
196 yield field
197 elif isinstance(field, list):
198 for item in field:
199 if isinstance(item, AST):
200 yield item
201
202
203def get_docstring(node, clean=True):
204 """
205 Return the docstring for the given node or None if no docstring can
206 be found. If the node provided does not have docstrings a TypeError
207 will be raised.
Matthias Bussonnier41cea702017-02-23 22:44:19 -0800208
209 If *clean* is `True`, all tabs are expanded to spaces and any whitespace
210 that can be uniformly removed from the second line onwards is removed.
Georg Brandl0c77a822008-06-10 16:37:50 +0000211 """
Yury Selivanov2f07a662015-07-23 08:54:35 +0300212 if not isinstance(node, (AsyncFunctionDef, FunctionDef, ClassDef, Module)):
Georg Brandl0c77a822008-06-10 16:37:50 +0000213 raise TypeError("%r can't have docstrings" % node.__class__.__name__)
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300214 if not(node.body and isinstance(node.body[0], Expr)):
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +0300215 return None
216 node = node.body[0].value
217 if isinstance(node, Str):
218 text = node.s
219 elif isinstance(node, Constant) and isinstance(node.value, str):
220 text = node.value
221 else:
222 return None
Serhiy Storchaka08f127a2018-06-15 11:05:15 +0300223 if clean:
Victor Stinnerf2c1aa12016-01-26 00:40:57 +0100224 import inspect
225 text = inspect.cleandoc(text)
226 return text
Georg Brandl0c77a822008-06-10 16:37:50 +0000227
228
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000229def _splitlines_no_ff(source):
230 """Split a string into lines ignoring form feed and other chars.
231
232 This mimics how the Python parser splits source code.
233 """
234 idx = 0
235 lines = []
236 next_line = ''
237 while idx < len(source):
238 c = source[idx]
239 next_line += c
240 idx += 1
241 # Keep \r\n together
242 if c == '\r' and idx < len(source) and source[idx] == '\n':
243 next_line += '\n'
244 idx += 1
245 if c in '\r\n':
246 lines.append(next_line)
247 next_line = ''
248
249 if next_line:
250 lines.append(next_line)
251 return lines
252
253
254def _pad_whitespace(source):
255 """Replace all chars except '\f\t' in a line with spaces."""
256 result = ''
257 for c in source:
258 if c in '\f\t':
259 result += c
260 else:
261 result += ' '
262 return result
263
264
265def get_source_segment(source, node, *, padded=False):
266 """Get source code segment of the *source* that generated *node*.
267
268 If some location information (`lineno`, `end_lineno`, `col_offset`,
269 or `end_col_offset`) is missing, return None.
270
271 If *padded* is `True`, the first line of a multi-line statement will
272 be padded with spaces to match its original position.
273 """
274 try:
275 lineno = node.lineno - 1
276 end_lineno = node.end_lineno - 1
277 col_offset = node.col_offset
278 end_col_offset = node.end_col_offset
279 except AttributeError:
280 return None
281
282 lines = _splitlines_no_ff(source)
283 if end_lineno == lineno:
284 return lines[lineno].encode()[col_offset:end_col_offset].decode()
285
286 if padded:
287 padding = _pad_whitespace(lines[lineno].encode()[:col_offset].decode())
288 else:
289 padding = ''
290
291 first = padding + lines[lineno].encode()[col_offset:].decode()
292 last = lines[end_lineno].encode()[:end_col_offset].decode()
293 lines = lines[lineno+1:end_lineno]
294
295 lines.insert(0, first)
296 lines.append(last)
297 return ''.join(lines)
298
299
Georg Brandl0c77a822008-06-10 16:37:50 +0000300def walk(node):
301 """
Georg Brandl619e7ba2011-01-09 07:38:51 +0000302 Recursively yield all descendant nodes in the tree starting at *node*
303 (including *node* itself), in no specified order. This is useful if you
304 only want to modify nodes in place and don't care about the context.
Georg Brandl0c77a822008-06-10 16:37:50 +0000305 """
306 from collections import deque
307 todo = deque([node])
308 while todo:
309 node = todo.popleft()
310 todo.extend(iter_child_nodes(node))
311 yield node
312
313
314class NodeVisitor(object):
315 """
316 A node visitor base class that walks the abstract syntax tree and calls a
317 visitor function for every node found. This function may return a value
318 which is forwarded by the `visit` method.
319
320 This class is meant to be subclassed, with the subclass adding visitor
321 methods.
322
323 Per default the visitor functions for the nodes are ``'visit_'`` +
324 class name of the node. So a `TryFinally` node visit function would
325 be `visit_TryFinally`. This behavior can be changed by overriding
326 the `visit` method. If no visitor function exists for a node
327 (return value `None`) the `generic_visit` visitor is used instead.
328
329 Don't use the `NodeVisitor` if you want to apply changes to nodes during
330 traversing. For this a special visitor exists (`NodeTransformer`) that
331 allows modifications.
332 """
333
334 def visit(self, node):
335 """Visit a node."""
336 method = 'visit_' + node.__class__.__name__
337 visitor = getattr(self, method, self.generic_visit)
338 return visitor(node)
339
340 def generic_visit(self, node):
341 """Called if no explicit visitor function exists for a node."""
342 for field, value in iter_fields(node):
343 if isinstance(value, list):
344 for item in value:
345 if isinstance(item, AST):
346 self.visit(item)
347 elif isinstance(value, AST):
348 self.visit(value)
349
350
351class NodeTransformer(NodeVisitor):
352 """
353 A :class:`NodeVisitor` subclass that walks the abstract syntax tree and
354 allows modification of nodes.
355
356 The `NodeTransformer` will walk the AST and use the return value of the
357 visitor methods to replace or remove the old node. If the return value of
358 the visitor method is ``None``, the node will be removed from its location,
359 otherwise it is replaced with the return value. The return value may be the
360 original node in which case no replacement takes place.
361
362 Here is an example transformer that rewrites all occurrences of name lookups
363 (``foo``) to ``data['foo']``::
364
365 class RewriteName(NodeTransformer):
366
367 def visit_Name(self, node):
368 return copy_location(Subscript(
369 value=Name(id='data', ctx=Load()),
370 slice=Index(value=Str(s=node.id)),
371 ctx=node.ctx
372 ), node)
373
374 Keep in mind that if the node you're operating on has child nodes you must
375 either transform the child nodes yourself or call the :meth:`generic_visit`
376 method for the node first.
377
378 For nodes that were part of a collection of statements (that applies to all
379 statement nodes), the visitor may also return a list of nodes rather than
380 just a single node.
381
382 Usually you use the transformer like this::
383
384 node = YourTransformer().visit(node)
385 """
386
387 def generic_visit(self, node):
388 for field, old_value in iter_fields(node):
Georg Brandl0c77a822008-06-10 16:37:50 +0000389 if isinstance(old_value, list):
390 new_values = []
391 for value in old_value:
392 if isinstance(value, AST):
393 value = self.visit(value)
394 if value is None:
395 continue
396 elif not isinstance(value, AST):
397 new_values.extend(value)
398 continue
399 new_values.append(value)
400 old_value[:] = new_values
401 elif isinstance(old_value, AST):
402 new_node = self.visit(old_value)
403 if new_node is None:
404 delattr(node, field)
405 else:
406 setattr(node, field, new_node)
407 return node
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300408
409
410# The following code is for backward compatibility.
411# It will be removed in future.
412
413def _getter(self):
414 return self.value
415
416def _setter(self, value):
417 self.value = value
418
419Constant.n = property(_getter, _setter)
420Constant.s = property(_getter, _setter)
421
422class _ABC(type):
423
424 def __instancecheck__(cls, inst):
425 if not isinstance(inst, Constant):
426 return False
427 if cls in _const_types:
428 try:
429 value = inst.value
430 except AttributeError:
431 return False
432 else:
Anthony Sottile74176222019-01-18 11:30:28 -0800433 return (
434 isinstance(value, _const_types[cls]) and
435 not isinstance(value, _const_types_not.get(cls, ()))
436 )
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300437 return type.__instancecheck__(cls, inst)
438
439def _new(cls, *args, **kwargs):
440 if cls in _const_types:
441 return Constant(*args, **kwargs)
442 return Constant.__new__(cls, *args, **kwargs)
443
444class Num(Constant, metaclass=_ABC):
445 _fields = ('n',)
446 __new__ = _new
447
448class Str(Constant, metaclass=_ABC):
449 _fields = ('s',)
450 __new__ = _new
451
452class Bytes(Constant, metaclass=_ABC):
453 _fields = ('s',)
454 __new__ = _new
455
456class NameConstant(Constant, metaclass=_ABC):
457 __new__ = _new
458
459class Ellipsis(Constant, metaclass=_ABC):
460 _fields = ()
461
462 def __new__(cls, *args, **kwargs):
463 if cls is Ellipsis:
464 return Constant(..., *args, **kwargs)
465 return Constant.__new__(cls, *args, **kwargs)
466
467_const_types = {
468 Num: (int, float, complex),
469 Str: (str,),
470 Bytes: (bytes,),
471 NameConstant: (type(None), bool),
472 Ellipsis: (type(...),),
473}
Anthony Sottile74176222019-01-18 11:30:28 -0800474_const_types_not = {
475 Num: (bool,),
476}