blob: 33464da734091e6c3ad208ae5a4f8b3089c53665 [file] [log] [blame]
adminbae64d82013-08-01 10:50:15 -07001# -*- coding: utf-8 -*-
2"""
3 ast
4 ~~~
5
6 The `ast` module helps Python applications to process trees of the Python
7 abstract syntax grammar. The abstract syntax itself might change with
8 each Python release; this module helps to find out programmatically what
9 the current grammar looks like and allows modifications of it.
10
11 An abstract syntax tree can be generated by passing `ast.PyCF_ONLY_AST` as
12 a flag to the `compile()` builtin function or by using the `parse()`
13 function from this module. The result will be a tree of objects whose
14 classes all inherit from `ast.AST`.
15
16 A modified abstract syntax tree can be compiled into a Python code object
17 using the built-in `compile()` function.
18
19 Additionally various helper functions are provided that make working with
20 the trees simpler. The main intention of the helper functions and this
21 module in general is to provide an easy to use interface for libraries
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070022 that work tightly with the python syntax ( template engines for example ).
adminbae64d82013-08-01 10:50:15 -070023
24
25 :copyright: Copyright 2008 by Armin Ronacher.
26 :license: Python License.
27"""
28from _ast import *
29from _ast import __version__
30
31
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070032def parse( source, filename='<unknown>', mode='exec' ):
adminbae64d82013-08-01 10:50:15 -070033 """
34 Parse the source into an AST node.
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070035 Equivalent to compile( source, filename, mode, PyCF_ONLY_AST ).
adminbae64d82013-08-01 10:50:15 -070036 """
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070037 return compile( source, filename, mode, PyCF_ONLY_AST )
adminbae64d82013-08-01 10:50:15 -070038
39
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070040def literal_eval( node_or_string ):
adminbae64d82013-08-01 10:50:15 -070041 """
42 Safely evaluate an expression node or a string containing a Python
43 expression. The string or node provided may only consist of the following
44 Python literal structures: strings, numbers, tuples, lists, dicts, booleans,
45 and None.
46 """
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070047 _safe_names = { 'None': None, 'True': True, 'False': False }
48 if isinstance( node_or_string, basestring ):
49 node_or_string = parse( node_or_string, mode='eval' )
50 if isinstance( node_or_string, Expression ):
adminbae64d82013-08-01 10:50:15 -070051 node_or_string = node_or_string.body
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070052
53 def _convert( node ):
54 if isinstance( node, Str ):
adminbae64d82013-08-01 10:50:15 -070055 return node.s
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070056 elif isinstance( node, Num ):
adminbae64d82013-08-01 10:50:15 -070057 return node.n
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070058 elif isinstance( node, Tuple ):
59 return tuple( map( _convert, node.elts ) )
60 elif isinstance( node, List ):
61 return list( map( _convert, node.elts ) )
62 elif isinstance( node, Dict ):
63 return dict( ( _convert( k ), _convert( v ) ) for k, v
64 in zip( node.keys, node.values ) )
65 elif isinstance( node, Name ):
adminbae64d82013-08-01 10:50:15 -070066 if node.id in _safe_names:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070067 return _safe_names[ node.id ]
68 elif isinstance( node, BinOp ) and \
69 isinstance( node.op, ( Add, Sub ) ) and \
70 isinstance( node.right, Num ) and \
71 isinstance( node.right.n, complex ) and \
72 isinstance( node.left, Num ) and \
73 isinstance( node.left.n, ( int, long, float ) ):
adminbae64d82013-08-01 10:50:15 -070074 left = node.left.n
75 right = node.right.n
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070076 if isinstance( node.op, Add ):
adminbae64d82013-08-01 10:50:15 -070077 return left + right
78 else:
79 return left - right
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070080 raise ValueError( 'malformed string' )
81 return _convert( node_or_string )
adminbae64d82013-08-01 10:50:15 -070082
83
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070084def dump( node, annotate_fields=True, include_attributes=False ):
adminbae64d82013-08-01 10:50:15 -070085 """
86 Return a formatted dump of the tree in *node*. This is mainly useful for
87 debugging purposes. The returned string will show the names and the values
88 for fields. This makes the code impossible to evaluate, so if evaluation is
89 wanted *annotate_fields* must be set to False. Attributes such as line
90 numbers and column offsets are not dumped by default. If this is wanted,
91 *include_attributes* can be set to True.
92 """
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070093 def _format( node ):
94 if isinstance( node, AST ):
95 fields = [ ( a, _format( b ) ) for a, b in iter_fields( node ) ]
96 rv = '%s(%s' % ( node.__class__.__name__, ', '.join(
97 ( '%s=%s' % field for field in fields )
adminbae64d82013-08-01 10:50:15 -070098 if annotate_fields else
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070099 ( b for a, b in fields )
100 ) )
adminbae64d82013-08-01 10:50:15 -0700101 if include_attributes and node._attributes:
102 rv += fields and ', ' or ' '
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700103 rv += ', '.join( '%s=%s' % ( a, _format( getattr( node, a ) ) )
104 for a in node._attributes )
adminbae64d82013-08-01 10:50:15 -0700105 return rv + ')'
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700106 elif isinstance( node, list ):
107 return '[%s]' % ', '.join( _format( x ) for x in node )
108 return repr( node )
109 if not isinstance( node, AST ):
110 raise TypeError( 'expected AST, got %r' % node.__class__.__name__ )
111 return _format( node )
adminbae64d82013-08-01 10:50:15 -0700112
113
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700114def copy_location( new_node, old_node ):
adminbae64d82013-08-01 10:50:15 -0700115 """
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700116 Copy source location ( `lineno` and `col_offset` attributes ) from
adminbae64d82013-08-01 10:50:15 -0700117 *old_node* to *new_node* if possible, and return *new_node*.
118 """
119 for attr in 'lineno', 'col_offset':
120 if attr in old_node._attributes and attr in new_node._attributes \
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700121 and hasattr( old_node, attr ):
122 setattr( new_node, attr, getattr( old_node, attr ) )
adminbae64d82013-08-01 10:50:15 -0700123 return new_node
124
125
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700126def fix_missing_locations( node ):
adminbae64d82013-08-01 10:50:15 -0700127 """
128 When you compile a node tree with compile(), the compiler expects lineno and
129 col_offset attributes for every node that supports them. This is rather
130 tedious to fill in for generated nodes, so this helper adds these attributes
131 recursively where not already set, by setting them to the values of the
132 parent node. It works recursively starting at *node*.
133 """
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700134 def _fix( node, lineno, col_offset ):
adminbae64d82013-08-01 10:50:15 -0700135 if 'lineno' in node._attributes:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700136 if not hasattr( node, 'lineno' ):
adminbae64d82013-08-01 10:50:15 -0700137 node.lineno = lineno
138 else:
139 lineno = node.lineno
140 if 'col_offset' in node._attributes:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700141 if not hasattr( node, 'col_offset' ):
adminbae64d82013-08-01 10:50:15 -0700142 node.col_offset = col_offset
143 else:
144 col_offset = node.col_offset
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700145 for child in iter_child_nodes( node ):
146 _fix( child, lineno, col_offset )
147 _fix( node, 1, 0 )
adminbae64d82013-08-01 10:50:15 -0700148 return node
149
150
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700151def increment_lineno( node, n=1 ):
adminbae64d82013-08-01 10:50:15 -0700152 """
153 Increment the line number of each node in the tree starting at *node* by *n*.
154 This is useful to "move code" to a different location in a file.
155 """
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700156 for child in walk( node ):
adminbae64d82013-08-01 10:50:15 -0700157 if 'lineno' in child._attributes:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700158 child.lineno = getattr( child, 'lineno', 0 ) + n
adminbae64d82013-08-01 10:50:15 -0700159 return node
160
161
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700162def iter_fields( node ):
adminbae64d82013-08-01 10:50:15 -0700163 """
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700164 Yield a tuple of ``( fieldname, value )`` for each field in ``node._fields``
adminbae64d82013-08-01 10:50:15 -0700165 that is present on *node*.
166 """
167 for field in node._fields:
168 try:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700169 yield field, getattr( node, field )
adminbae64d82013-08-01 10:50:15 -0700170 except AttributeError:
171 pass
172
173
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700174def iter_child_nodes( node ):
adminbae64d82013-08-01 10:50:15 -0700175 """
176 Yield all direct child nodes of *node*, that is, all fields that are nodes
177 and all items of fields that are lists of nodes.
178 """
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700179 for name, field in iter_fields( node ):
180 if isinstance( field, AST ):
adminbae64d82013-08-01 10:50:15 -0700181 yield field
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700182 elif isinstance( field, list ):
adminbae64d82013-08-01 10:50:15 -0700183 for item in field:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700184 if isinstance( item, AST ):
adminbae64d82013-08-01 10:50:15 -0700185 yield item
186
187
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700188def get_docstring( node, clean=True ):
adminbae64d82013-08-01 10:50:15 -0700189 """
190 Return the docstring for the given node or None if no docstring can
191 be found. If the node provided does not have docstrings a TypeError
192 will be raised.
193 """
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700194 if not isinstance( node, ( FunctionDef, ClassDef, Module ) ):
195 raise TypeError( "%r can't have docstrings" % node.__class__.__name__ )
196 if node.body and isinstance( node.body[ 0 ], Expr ) and \
197 isinstance( node.body[ 0 ].value, Str ):
adminbae64d82013-08-01 10:50:15 -0700198 if clean:
199 import inspect
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700200 return inspect.cleandoc( node.body[ 0 ].value.s )
201 return node.body[ 0 ].value.s
adminbae64d82013-08-01 10:50:15 -0700202
203
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700204def walk( node ):
adminbae64d82013-08-01 10:50:15 -0700205 """
206 Recursively yield all descendant nodes in the tree starting at *node*
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700207 ( including *node* itself ), in no specified order. This is useful if you
adminbae64d82013-08-01 10:50:15 -0700208 only want to modify nodes in place and don't care about the context.
209 """
210 from collections import deque
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700211 todo = deque( [ node ] )
adminbae64d82013-08-01 10:50:15 -0700212 while todo:
213 node = todo.popleft()
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700214 todo.extend( iter_child_nodes( node ) )
adminbae64d82013-08-01 10:50:15 -0700215 yield node
216
217
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700218class NodeVisitor( object ):
219
adminbae64d82013-08-01 10:50:15 -0700220 """
221 A node visitor base class that walks the abstract syntax tree and calls a
222 visitor function for every node found. This function may return a value
223 which is forwarded by the `visit` method.
224
225 This class is meant to be subclassed, with the subclass adding visitor
226 methods.
227
228 Per default the visitor functions for the nodes are ``'visit_'`` +
229 class name of the node. So a `TryFinally` node visit function would
230 be `visit_TryFinally`. This behavior can be changed by overriding
231 the `visit` method. If no visitor function exists for a node
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700232 ( return value `None` ) the `generic_visit` visitor is used instead.
adminbae64d82013-08-01 10:50:15 -0700233
234 Don't use the `NodeVisitor` if you want to apply changes to nodes during
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700235 traversing. For this a special visitor exists ( `NodeTransformer` ) that
adminbae64d82013-08-01 10:50:15 -0700236 allows modifications.
237 """
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700238 def visit( self, node ):
239 "Visit a node."
adminbae64d82013-08-01 10:50:15 -0700240 method = 'visit_' + node.__class__.__name__
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700241 visitor = getattr( self, method, self.generic_visit )
242 return visitor( node )
adminbae64d82013-08-01 10:50:15 -0700243
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700244 def generic_visit( self, node ):
245 "Called if no explicit visitor function exists for a node."
246 for field, value in iter_fields( node ):
247 if isinstance( value, list ):
adminbae64d82013-08-01 10:50:15 -0700248 for item in value:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700249 if isinstance( item, AST ):
250 self.visit( item )
251 elif isinstance( value, AST ):
252 self.visit( value )
adminbae64d82013-08-01 10:50:15 -0700253
254
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700255class NodeTransformer( NodeVisitor ):
256
adminbae64d82013-08-01 10:50:15 -0700257 """
258 A :class:`NodeVisitor` subclass that walks the abstract syntax tree and
259 allows modification of nodes.
260
261 The `NodeTransformer` will walk the AST and use the return value of the
262 visitor methods to replace or remove the old node. If the return value of
263 the visitor method is ``None``, the node will be removed from its location,
264 otherwise it is replaced with the return value. The return value may be the
265 original node in which case no replacement takes place.
266
267 Here is an example transformer that rewrites all occurrences of name lookups
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700268 ( ``foo`` ) to ``data[ 'foo' ]``::
adminbae64d82013-08-01 10:50:15 -0700269
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700270 class RewriteName( NodeTransformer ):
adminbae64d82013-08-01 10:50:15 -0700271
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700272 def visit_Name( self, node ):
273 return copy_location( Subscript(
274 value=Name( id='data', ctx=Load() ),
275 slice=Index( value=Str( s=node.id ) ),
adminbae64d82013-08-01 10:50:15 -0700276 ctx=node.ctx
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700277 ), node )
adminbae64d82013-08-01 10:50:15 -0700278
279 Keep in mind that if the node you're operating on has child nodes you must
280 either transform the child nodes yourself or call the :meth:`generic_visit`
281 method for the node first.
282
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700283 For nodes that were part of a collection of statements ( that applies to all
284 statement nodes ), the visitor may also return a list of nodes rather than
adminbae64d82013-08-01 10:50:15 -0700285 just a single node.
286
287 Usually you use the transformer like this::
288
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700289 node = YourTransformer().visit( node )
adminbae64d82013-08-01 10:50:15 -0700290 """
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700291 def generic_visit( self, node ):
292 for field, old_value in iter_fields( node ):
293 old_value = getattr( node, field, None )
294 if isinstance( old_value, list ):
adminbae64d82013-08-01 10:50:15 -0700295 new_values = []
296 for value in old_value:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700297 if isinstance( value, AST ):
298 value = self.visit( value )
adminbae64d82013-08-01 10:50:15 -0700299 if value is None:
300 continue
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700301 elif not isinstance( value, AST ):
302 new_values.extend( value )
adminbae64d82013-08-01 10:50:15 -0700303 continue
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700304 new_values.append( value )
305 old_value[ : ] = new_values
306 elif isinstance( old_value, AST ):
307 new_node = self.visit( old_value )
adminbae64d82013-08-01 10:50:15 -0700308 if new_node is None:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700309 delattr( node, field )
adminbae64d82013-08-01 10:50:15 -0700310 else:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700311 setattr( node, field, new_node )
adminbae64d82013-08-01 10:50:15 -0700312 return node