@@ -1134,6 +1134,9 @@ def remap(root, visit=default_visit, enter=default_enter, exit=default_exit,
1134
1134
callable. When set to ``False``, remap ignores any errors
1135
1135
raised by the *visit* callback. Items causing exceptions
1136
1136
are kept. See examples for more details.
1137
+ trace (bool): Pass ``trace=True`` to print out the entire
1138
+ traversal. Or pass a tuple of ``'visit'``, ``'enter'``,
1139
+ or ``'exit'`` to print only the selected events.
1137
1140
1138
1141
remap is designed to cover the majority of cases with just the
1139
1142
*visit* callable. While passing in multiple callables is very
@@ -1162,6 +1165,15 @@ def remap(root, visit=default_visit, enter=default_enter, exit=default_exit,
1162
1165
if not callable (exit ):
1163
1166
raise TypeError ('exit expected callable, not: %r' % exit )
1164
1167
reraise_visit = kwargs .pop ('reraise_visit' , True )
1168
+ trace = kwargs .pop ('trace' , ())
1169
+ if trace is True :
1170
+ trace = ('visit' , 'enter' , 'exit' )
1171
+ elif isinstance (trace , str ):
1172
+ trace = (trace ,)
1173
+ if not isinstance (trace , (tuple , list , set )):
1174
+ raise TypeError ('trace expected tuple of event names, not: %r' % trace )
1175
+ trace_enter , trace_exit , trace_visit = 'enter' in trace , 'exit' in trace , 'visit' in trace
1176
+
1165
1177
if kwargs :
1166
1178
raise TypeError ('unexpected keyword arguments: %r' % kwargs .keys ())
1167
1179
@@ -1174,14 +1186,23 @@ def remap(root, visit=default_visit, enter=default_enter, exit=default_exit,
1174
1186
key , new_parent , old_parent = value
1175
1187
id_value = id (old_parent )
1176
1188
path , new_items = new_items_stack .pop ()
1189
+ if trace_exit :
1190
+ print (' .. remap exit:' , path , '-' , key , '-' ,
1191
+ old_parent , '-' , new_parent , '-' , new_items )
1177
1192
value = exit (path , key , old_parent , new_parent , new_items )
1193
+ if trace_exit :
1194
+ print (' .. remap exit result:' , value )
1178
1195
registry [id_value ] = value
1179
1196
if not new_items_stack :
1180
1197
continue
1181
1198
elif id_value in registry :
1182
1199
value = registry [id_value ]
1183
1200
else :
1201
+ if trace_enter :
1202
+ print (' .. remap enter:' , path , '-' , key , '-' , value )
1184
1203
res = enter (path , key , value )
1204
+ if trace_enter :
1205
+ print (' .. remap enter result:' , res )
1185
1206
try :
1186
1207
new_parent , new_items = res
1187
1208
except TypeError :
@@ -1197,21 +1218,29 @@ def remap(root, visit=default_visit, enter=default_enter, exit=default_exit,
1197
1218
stack .append ((_REMAP_EXIT , (key , new_parent , value )))
1198
1219
if new_items :
1199
1220
stack .extend (reversed (list (new_items )))
1221
+ if trace_enter :
1222
+ print (' .. remap stack size now:' , len (stack ))
1200
1223
continue
1201
1224
if visit is _orig_default_visit :
1202
1225
# avoid function call overhead by inlining identity operation
1203
1226
visited_item = (key , value )
1204
1227
else :
1205
1228
try :
1229
+ if trace_visit :
1230
+ print (' .. remap visit:' , path , '-' , key , '-' , value )
1206
1231
visited_item = visit (path , key , value )
1207
1232
except Exception :
1208
1233
if reraise_visit :
1209
1234
raise
1210
1235
visited_item = True
1211
1236
if visited_item is False :
1237
+ if trace_visit :
1238
+ print (' .. remap visit result: <drop>' )
1212
1239
continue # drop
1213
1240
elif visited_item is True :
1214
1241
visited_item = (key , value )
1242
+ if trace_visit :
1243
+ print (' .. remap visit result:' , visited_item )
1215
1244
# TODO: typecheck?
1216
1245
# raise TypeError('expected (key, value) from visit(),'
1217
1246
# ' not: %r' % visited_item)
0 commit comments