@@ -96,43 +96,66 @@ def _convert(node):
9696 return _convert (node_or_string )
9797
9898
99- def dump (node , annotate_fields = True , include_attributes = False ):
99+ def dump (node , annotate_fields = True , include_attributes = False , * , indent = None ):
100100 """
101101 Return a formatted dump of the tree in node. This is mainly useful for
102102 debugging purposes. If annotate_fields is true (by default),
103103 the returned string will show the names and the values for fields.
104104 If annotate_fields is false, the result string will be more compact by
105105 omitting unambiguous field names. Attributes such as line
106106 numbers and column offsets are not dumped by default. If this is wanted,
107- include_attributes can be set to true.
107+ include_attributes can be set to true. If indent is a non-negative
108+ integer or string, then the tree will be pretty-printed with that indent
109+ level. None (the default) selects the single line representation.
108110 """
109- def _format (node ):
111+ def _format (node , level = 0 ):
112+ if indent is not None :
113+ level += 1
114+ prefix = '\n ' + indent * level
115+ sep = ',\n ' + indent * level
116+ else :
117+ prefix = ''
118+ sep = ', '
110119 if isinstance (node , AST ):
111120 args = []
121+ allsimple = True
112122 keywords = annotate_fields
113123 for field in node ._fields :
114124 try :
115125 value = getattr (node , field )
116126 except AttributeError :
117127 keywords = True
118128 else :
129+ value , simple = _format (value , level )
130+ allsimple = allsimple and simple
119131 if keywords :
120- args .append ('%s=%s' % (field , _format ( value ) ))
132+ args .append ('%s=%s' % (field , value ))
121133 else :
122- args .append (_format ( value ) )
134+ args .append (value )
123135 if include_attributes and node ._attributes :
124- for a in node ._attributes :
136+ for attr in node ._attributes :
125137 try :
126- args . append ( '%s=%s' % ( a , _format ( getattr (node , a ))) )
138+ value = getattr (node , attr )
127139 except AttributeError :
128140 pass
129- return '%s(%s)' % (node .__class__ .__name__ , ', ' .join (args ))
141+ else :
142+ value , simple = _format (value , level )
143+ allsimple = allsimple and simple
144+ args .append ('%s=%s' % (attr , value ))
145+ if allsimple and len (args ) <= 3 :
146+ return '%s(%s)' % (node .__class__ .__name__ , ', ' .join (args )), not args
147+ return '%s(%s%s)' % (node .__class__ .__name__ , prefix , sep .join (args )), False
130148 elif isinstance (node , list ):
131- return '[%s]' % ', ' .join (_format (x ) for x in node )
132- return repr (node )
149+ if not node :
150+ return '[]' , True
151+ return '[%s%s]' % (prefix , sep .join (_format (x , level )[0 ] for x in node )), False
152+ return repr (node ), True
153+
133154 if not isinstance (node , AST ):
134155 raise TypeError ('expected AST, got %r' % node .__class__ .__name__ )
135- return _format (node )
156+ if indent is not None and not isinstance (indent , str ):
157+ indent = ' ' * indent
158+ return _format (node )[0 ]
136159
137160
138161def copy_location (new_node , old_node ):
0 commit comments