blob: 1b1ff291f9a49975c3b8d27ac707907d938adace [file] [log] [blame]
Tim Peters400cbc32006-02-28 18:44:41 +00001"Usage: unparse.py <path to source file>"
2import sys
Mark Dickinson20379132010-06-30 14:19:56 +00003import ast
Martin v. Löwis3fa6c092006-04-10 12:43:55 +00004import cStringIO
5import os
Tim Peters400cbc32006-02-28 18:44:41 +00006
Mark Dickinson20379132010-06-30 14:19:56 +00007# Large float and imaginary literals get turned into infinities in the AST.
8# We unparse those infinities to INFSTR.
9INFSTR = "1e" + repr(sys.float_info.max_10_exp + 1)
10
Georg Brandl124df832007-03-19 19:02:48 +000011def interleave(inter, f, seq):
12 """Call f on each item in seq, calling inter() in between.
13 """
14 seq = iter(seq)
15 try:
Mark Dickinson20379132010-06-30 14:19:56 +000016 f(next(seq))
Tim Peters35c7bb22007-04-25 18:47:18 +000017 except StopIteration:
Georg Brandl124df832007-03-19 19:02:48 +000018 pass
19 else:
20 for x in seq:
21 inter()
22 f(x)
23
Tim Peters400cbc32006-02-28 18:44:41 +000024class Unparser:
25 """Methods in this class recursively traverse an AST and
26 output source code for the abstract syntax; original formatting
Mark Dickinson20379132010-06-30 14:19:56 +000027 is disregarded. """
Tim Peters400cbc32006-02-28 18:44:41 +000028
29 def __init__(self, tree, file = sys.stdout):
30 """Unparser(tree, file=sys.stdout) -> None.
31 Print the source for tree to file."""
32 self.f = file
Mark Dickinson20379132010-06-30 14:19:56 +000033 self.future_imports = []
Tim Peters400cbc32006-02-28 18:44:41 +000034 self._indent = 0
35 self.dispatch(tree)
Mark Dickinson20379132010-06-30 14:19:56 +000036 self.f.write("")
Tim Peters400cbc32006-02-28 18:44:41 +000037 self.f.flush()
38
39 def fill(self, text = ""):
40 "Indent a piece of text, according to the current indentation level"
41 self.f.write("\n"+" "*self._indent + text)
42
43 def write(self, text):
44 "Append a piece of text to the current line."
45 self.f.write(text)
46
47 def enter(self):
48 "Print ':', and increase the indentation."
49 self.write(":")
50 self._indent += 1
51
52 def leave(self):
53 "Decrease the indentation level."
54 self._indent -= 1
55
56 def dispatch(self, tree):
57 "Dispatcher function, dispatching tree type T to method _T."
58 if isinstance(tree, list):
59 for t in tree:
60 self.dispatch(t)
61 return
62 meth = getattr(self, "_"+tree.__class__.__name__)
63 meth(tree)
64
65
66 ############### Unparsing methods ######################
67 # There should be one method per concrete grammar type #
68 # Constructors should be grouped by sum type. Ideally, #
69 # this would follow the order in the grammar, but #
70 # currently doesn't. #
71 ########################################################
72
73 def _Module(self, tree):
74 for stmt in tree.body:
75 self.dispatch(stmt)
76
77 # stmt
78 def _Expr(self, tree):
79 self.fill()
80 self.dispatch(tree.value)
81
82 def _Import(self, t):
83 self.fill("import ")
Georg Brandl124df832007-03-19 19:02:48 +000084 interleave(lambda: self.write(", "), self.dispatch, t.names)
Tim Peters3daf3042006-04-10 20:28:40 +000085
Martin v. Löwis3fa6c092006-04-10 12:43:55 +000086 def _ImportFrom(self, t):
Mark Dickinson20379132010-06-30 14:19:56 +000087 # A from __future__ import may affect unparsing, so record it.
88 if t.module and t.module == '__future__':
89 self.future_imports.extend(n.name for n in t.names)
90
Martin v. Löwis3fa6c092006-04-10 12:43:55 +000091 self.fill("from ")
Mark Dickinson20379132010-06-30 14:19:56 +000092 self.write("." * t.level)
93 if t.module:
94 self.write(t.module)
Martin v. Löwis3fa6c092006-04-10 12:43:55 +000095 self.write(" import ")
Georg Brandl124df832007-03-19 19:02:48 +000096 interleave(lambda: self.write(", "), self.dispatch, t.names)
Tim Peters400cbc32006-02-28 18:44:41 +000097
98 def _Assign(self, t):
99 self.fill()
100 for target in t.targets:
101 self.dispatch(target)
102 self.write(" = ")
103 self.dispatch(t.value)
104
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000105 def _AugAssign(self, t):
106 self.fill()
107 self.dispatch(t.target)
108 self.write(" "+self.binop[t.op.__class__.__name__]+"= ")
109 self.dispatch(t.value)
110
111 def _Return(self, t):
Georg Brandl124df832007-03-19 19:02:48 +0000112 self.fill("return")
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000113 if t.value:
Georg Brandl124df832007-03-19 19:02:48 +0000114 self.write(" ")
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000115 self.dispatch(t.value)
116
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000117 def _Pass(self, t):
118 self.fill("pass")
Tim Peters3daf3042006-04-10 20:28:40 +0000119
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000120 def _Break(self, t):
121 self.fill("break")
122
123 def _Continue(self, t):
124 self.fill("continue")
Tim Peters3daf3042006-04-10 20:28:40 +0000125
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000126 def _Delete(self, t):
127 self.fill("del ")
Mark Dickinson623b9792010-06-28 19:31:41 +0000128 interleave(lambda: self.write(", "), self.dispatch, t.targets)
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000129
130 def _Assert(self, t):
131 self.fill("assert ")
132 self.dispatch(t.test)
133 if t.msg:
134 self.write(", ")
135 self.dispatch(t.msg)
Tim Peters3daf3042006-04-10 20:28:40 +0000136
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000137 def _Exec(self, t):
138 self.fill("exec ")
139 self.dispatch(t.body)
140 if t.globals:
141 self.write(" in ")
142 self.dispatch(t.globals)
143 if t.locals:
144 self.write(", ")
145 self.dispatch(t.locals)
146
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000147 def _Print(self, t):
148 self.fill("print ")
149 do_comma = False
150 if t.dest:
151 self.write(">>")
152 self.dispatch(t.dest)
153 do_comma = True
154 for e in t.values:
155 if do_comma:self.write(", ")
156 else:do_comma=True
157 self.dispatch(e)
158 if not t.nl:
159 self.write(",")
160
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000161 def _Global(self, t):
Georg Brandl124df832007-03-19 19:02:48 +0000162 self.fill("global ")
163 interleave(lambda: self.write(", "), self.write, t.names)
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000164
165 def _Yield(self, t):
Georg Brandl124df832007-03-19 19:02:48 +0000166 self.write("(")
167 self.write("yield")
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000168 if t.value:
Georg Brandl124df832007-03-19 19:02:48 +0000169 self.write(" ")
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000170 self.dispatch(t.value)
Georg Brandl124df832007-03-19 19:02:48 +0000171 self.write(")")
Tim Peters3daf3042006-04-10 20:28:40 +0000172
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000173 def _Raise(self, t):
174 self.fill('raise ')
175 if t.type:
176 self.dispatch(t.type)
177 if t.inst:
178 self.write(", ")
179 self.dispatch(t.inst)
180 if t.tback:
181 self.write(", ")
182 self.dispatch(t.tback)
Tim Peters3daf3042006-04-10 20:28:40 +0000183
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000184 def _TryExcept(self, t):
185 self.fill("try")
186 self.enter()
187 self.dispatch(t.body)
188 self.leave()
Tim Peters3daf3042006-04-10 20:28:40 +0000189
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000190 for ex in t.handlers:
191 self.dispatch(ex)
192 if t.orelse:
193 self.fill("else")
194 self.enter()
195 self.dispatch(t.orelse)
196 self.leave()
197
198 def _TryFinally(self, t):
Mark Dickinson20379132010-06-30 14:19:56 +0000199 if len(t.body) == 1 and isinstance(t.body[0], ast.TryExcept):
200 # try-except-finally
201 self.dispatch(t.body)
202 else:
203 self.fill("try")
204 self.enter()
205 self.dispatch(t.body)
206 self.leave()
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000207
208 self.fill("finally")
209 self.enter()
210 self.dispatch(t.finalbody)
211 self.leave()
212
Benjamin Peterson7c972f92008-08-19 17:59:23 +0000213 def _ExceptHandler(self, t):
Georg Brandl124df832007-03-19 19:02:48 +0000214 self.fill("except")
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000215 if t.type:
Georg Brandl124df832007-03-19 19:02:48 +0000216 self.write(" ")
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000217 self.dispatch(t.type)
218 if t.name:
Mark Dickinson20379132010-06-30 14:19:56 +0000219 self.write(" as ")
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000220 self.dispatch(t.name)
221 self.enter()
222 self.dispatch(t.body)
223 self.leave()
Tim Peters3daf3042006-04-10 20:28:40 +0000224
Tim Peters400cbc32006-02-28 18:44:41 +0000225 def _ClassDef(self, t):
226 self.write("\n")
Mark Dickinson20379132010-06-30 14:19:56 +0000227 for deco in t.decorator_list:
228 self.fill("@")
229 self.dispatch(deco)
Tim Peters400cbc32006-02-28 18:44:41 +0000230 self.fill("class "+t.name)
231 if t.bases:
232 self.write("(")
233 for a in t.bases:
234 self.dispatch(a)
235 self.write(", ")
236 self.write(")")
237 self.enter()
238 self.dispatch(t.body)
239 self.leave()
240
241 def _FunctionDef(self, t):
242 self.write("\n")
Benjamin Peterson7c972f92008-08-19 17:59:23 +0000243 for deco in t.decorator_list:
Georg Brandl27562782006-10-27 20:39:43 +0000244 self.fill("@")
245 self.dispatch(deco)
Tim Peters400cbc32006-02-28 18:44:41 +0000246 self.fill("def "+t.name + "(")
247 self.dispatch(t.args)
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000248 self.write(")")
Tim Peters400cbc32006-02-28 18:44:41 +0000249 self.enter()
250 self.dispatch(t.body)
251 self.leave()
252
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000253 def _For(self, t):
254 self.fill("for ")
255 self.dispatch(t.target)
256 self.write(" in ")
257 self.dispatch(t.iter)
258 self.enter()
259 self.dispatch(t.body)
260 self.leave()
261 if t.orelse:
262 self.fill("else")
263 self.enter()
264 self.dispatch(t.orelse)
Mark Dickinson623b9792010-06-28 19:31:41 +0000265 self.leave()
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000266
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000267 def _If(self, t):
268 self.fill("if ")
269 self.dispatch(t.test)
270 self.enter()
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000271 self.dispatch(t.body)
272 self.leave()
Mark Dickinson20379132010-06-30 14:19:56 +0000273 # collapse nested ifs into equivalent elifs.
274 while (t.orelse and len(t.orelse) == 1 and
275 isinstance(t.orelse[0], ast.If)):
276 t = t.orelse[0]
277 self.fill("elif ")
278 self.dispatch(t.test)
279 self.enter()
280 self.dispatch(t.body)
281 self.leave()
282 # final else
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000283 if t.orelse:
284 self.fill("else")
285 self.enter()
286 self.dispatch(t.orelse)
287 self.leave()
288
289 def _While(self, t):
290 self.fill("while ")
291 self.dispatch(t.test)
292 self.enter()
293 self.dispatch(t.body)
294 self.leave()
295 if t.orelse:
296 self.fill("else")
297 self.enter()
298 self.dispatch(t.orelse)
Mark Dickinson623b9792010-06-28 19:31:41 +0000299 self.leave()
Tim Peters3daf3042006-04-10 20:28:40 +0000300
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000301 def _With(self, t):
302 self.fill("with ")
303 self.dispatch(t.context_expr)
304 if t.optional_vars:
305 self.write(" as ")
306 self.dispatch(t.optional_vars)
307 self.enter()
308 self.dispatch(t.body)
309 self.leave()
310
Tim Peters400cbc32006-02-28 18:44:41 +0000311 # expr
312 def _Str(self, tree):
Mark Dickinson20379132010-06-30 14:19:56 +0000313 # if from __future__ import unicode_literals is in effect,
314 # then we want to output string literals using a 'b' prefix
315 # and unicode literals with no prefix.
316 if "unicode_literals" not in self.future_imports:
317 self.write(repr(tree.s))
318 elif isinstance(tree.s, str):
319 self.write("b" + repr(tree.s))
320 elif isinstance(tree.s, unicode):
321 self.write(repr(tree.s).lstrip("u"))
322 else:
323 assert False, "shouldn't get here"
Tim Peters400cbc32006-02-28 18:44:41 +0000324
325 def _Name(self, t):
326 self.write(t.id)
327
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000328 def _Repr(self, t):
329 self.write("`")
330 self.dispatch(t.value)
331 self.write("`")
Tim Peters3daf3042006-04-10 20:28:40 +0000332
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000333 def _Num(self, t):
Mark Dickinson20379132010-06-30 14:19:56 +0000334 repr_n = repr(t.n)
335 # Parenthesize negative numbers, to avoid turning (-1)**2 into -1**2.
336 if repr_n.startswith("-"):
Mark Dickinson623b9792010-06-28 19:31:41 +0000337 self.write("(")
Mark Dickinson20379132010-06-30 14:19:56 +0000338 # Substitute overflowing decimal literal for AST infinities.
339 self.write(repr_n.replace("inf", INFSTR))
340 if repr_n.startswith("-"):
Mark Dickinson623b9792010-06-28 19:31:41 +0000341 self.write(")")
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000342
Tim Peters400cbc32006-02-28 18:44:41 +0000343 def _List(self, t):
344 self.write("[")
Georg Brandl124df832007-03-19 19:02:48 +0000345 interleave(lambda: self.write(", "), self.dispatch, t.elts)
Tim Peters400cbc32006-02-28 18:44:41 +0000346 self.write("]")
347
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000348 def _ListComp(self, t):
349 self.write("[")
350 self.dispatch(t.elt)
351 for gen in t.generators:
352 self.dispatch(gen)
353 self.write("]")
Tim Peters3daf3042006-04-10 20:28:40 +0000354
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000355 def _GeneratorExp(self, t):
356 self.write("(")
357 self.dispatch(t.elt)
358 for gen in t.generators:
359 self.dispatch(gen)
360 self.write(")")
Tim Peters3daf3042006-04-10 20:28:40 +0000361
Mark Dickinson20379132010-06-30 14:19:56 +0000362 def _SetComp(self, t):
363 self.write("{")
364 self.dispatch(t.elt)
365 for gen in t.generators:
366 self.dispatch(gen)
367 self.write("}")
368
369 def _DictComp(self, t):
370 self.write("{")
371 self.dispatch(t.key)
372 self.write(": ")
373 self.dispatch(t.value)
374 for gen in t.generators:
375 self.dispatch(gen)
376 self.write("}")
377
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000378 def _comprehension(self, t):
379 self.write(" for ")
380 self.dispatch(t.target)
381 self.write(" in ")
382 self.dispatch(t.iter)
383 for if_clause in t.ifs:
384 self.write(" if ")
385 self.dispatch(if_clause)
386
387 def _IfExp(self, t):
Georg Brandl124df832007-03-19 19:02:48 +0000388 self.write("(")
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000389 self.dispatch(t.body)
390 self.write(" if ")
391 self.dispatch(t.test)
Georg Brandl124df832007-03-19 19:02:48 +0000392 self.write(" else ")
393 self.dispatch(t.orelse)
394 self.write(")")
Tim Peters3daf3042006-04-10 20:28:40 +0000395
Mark Dickinson20379132010-06-30 14:19:56 +0000396 def _Set(self, t):
397 assert(t.elts) # should be at least one element
398 self.write("{")
399 interleave(lambda: self.write(", "), self.dispatch, t.elts)
400 self.write("}")
401
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000402 def _Dict(self, t):
403 self.write("{")
Mark Dickinson20379132010-06-30 14:19:56 +0000404 def write_pair(pair):
405 (k, v) = pair
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000406 self.dispatch(k)
Georg Brandl124df832007-03-19 19:02:48 +0000407 self.write(": ")
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000408 self.dispatch(v)
Mark Dickinson20379132010-06-30 14:19:56 +0000409 interleave(lambda: self.write(", "), write_pair, zip(t.keys, t.values))
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000410 self.write("}")
411
412 def _Tuple(self, t):
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000413 self.write("(")
Georg Brandl124df832007-03-19 19:02:48 +0000414 if len(t.elts) == 1:
415 (elt,) = t.elts
416 self.dispatch(elt)
417 self.write(",")
418 else:
419 interleave(lambda: self.write(", "), self.dispatch, t.elts)
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000420 self.write(")")
421
Tim Peters400cbc32006-02-28 18:44:41 +0000422 unop = {"Invert":"~", "Not": "not", "UAdd":"+", "USub":"-"}
423 def _UnaryOp(self, t):
Tim Peters400cbc32006-02-28 18:44:41 +0000424 self.write("(")
Mark Dickinson623b9792010-06-28 19:31:41 +0000425 self.write(self.unop[t.op.__class__.__name__])
426 self.write(" ")
Mark Dickinson20379132010-06-30 14:19:56 +0000427 # If we're applying unary minus to a number, parenthesize the number.
428 # This is necessary: -2147483648 is different from -(2147483648) on
429 # a 32-bit machine (the first is an int, the second a long), and
430 # -7j is different from -(7j). (The first has real part 0.0, the second
431 # has real part -0.0.)
432 if isinstance(t.op, ast.USub) and isinstance(t.operand, ast.Num):
433 self.write("(")
434 self.dispatch(t.operand)
435 self.write(")")
436 else:
437 self.dispatch(t.operand)
Tim Peters400cbc32006-02-28 18:44:41 +0000438 self.write(")")
439
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000440 binop = { "Add":"+", "Sub":"-", "Mult":"*", "Div":"/", "Mod":"%",
Mark Dickinson623b9792010-06-28 19:31:41 +0000441 "LShift":"<<", "RShift":">>", "BitOr":"|", "BitXor":"^", "BitAnd":"&",
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000442 "FloorDiv":"//", "Pow": "**"}
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000443 def _BinOp(self, t):
444 self.write("(")
445 self.dispatch(t.left)
Georg Brandl124df832007-03-19 19:02:48 +0000446 self.write(" " + self.binop[t.op.__class__.__name__] + " ")
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000447 self.dispatch(t.right)
448 self.write(")")
449
450 cmpops = {"Eq":"==", "NotEq":"!=", "Lt":"<", "LtE":"<=", "Gt":">", "GtE":">=",
451 "Is":"is", "IsNot":"is not", "In":"in", "NotIn":"not in"}
452 def _Compare(self, t):
453 self.write("(")
454 self.dispatch(t.left)
455 for o, e in zip(t.ops, t.comparators):
Georg Brandl124df832007-03-19 19:02:48 +0000456 self.write(" " + self.cmpops[o.__class__.__name__] + " ")
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000457 self.dispatch(e)
Mark Dickinson0187be02010-06-28 19:54:19 +0000458 self.write(")")
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000459
Mark Dickinson20379132010-06-30 14:19:56 +0000460 boolops = {ast.And: 'and', ast.Or: 'or'}
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000461 def _BoolOp(self, t):
462 self.write("(")
Georg Brandl124df832007-03-19 19:02:48 +0000463 s = " %s " % self.boolops[t.op.__class__]
464 interleave(lambda: self.write(s), self.dispatch, t.values)
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000465 self.write(")")
Tim Peters3daf3042006-04-10 20:28:40 +0000466
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000467 def _Attribute(self,t):
468 self.dispatch(t.value)
Mark Dickinson20379132010-06-30 14:19:56 +0000469 # Special case: 3.__abs__() is a syntax error, so if t.value
470 # is an integer literal then we need to either parenthesize
471 # it or add an extra space to get 3 .__abs__().
472 if isinstance(t.value, ast.Num) and isinstance(t.value.n, int):
473 self.write(" ")
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000474 self.write(".")
475 self.write(t.attr)
476
477 def _Call(self, t):
478 self.dispatch(t.func)
479 self.write("(")
480 comma = False
481 for e in t.args:
482 if comma: self.write(", ")
483 else: comma = True
484 self.dispatch(e)
485 for e in t.keywords:
486 if comma: self.write(", ")
487 else: comma = True
488 self.dispatch(e)
489 if t.starargs:
490 if comma: self.write(", ")
491 else: comma = True
492 self.write("*")
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000493 self.dispatch(t.starargs)
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000494 if t.kwargs:
495 if comma: self.write(", ")
496 else: comma = True
497 self.write("**")
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000498 self.dispatch(t.kwargs)
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000499 self.write(")")
500
501 def _Subscript(self, t):
502 self.dispatch(t.value)
503 self.write("[")
504 self.dispatch(t.slice)
505 self.write("]")
506
507 # slice
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000508 def _Ellipsis(self, t):
509 self.write("...")
Tim Peters3daf3042006-04-10 20:28:40 +0000510
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000511 def _Index(self, t):
512 self.dispatch(t.value)
513
514 def _Slice(self, t):
515 if t.lower:
516 self.dispatch(t.lower)
517 self.write(":")
518 if t.upper:
519 self.dispatch(t.upper)
520 if t.step:
521 self.write(":")
522 self.dispatch(t.step)
523
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000524 def _ExtSlice(self, t):
Georg Brandl124df832007-03-19 19:02:48 +0000525 interleave(lambda: self.write(', '), self.dispatch, t.dims)
Tim Peters3daf3042006-04-10 20:28:40 +0000526
Tim Peters400cbc32006-02-28 18:44:41 +0000527 # others
528 def _arguments(self, t):
529 first = True
Mark Dickinson20379132010-06-30 14:19:56 +0000530 # normal arguments
531 defaults = [None] * (len(t.args) - len(t.defaults)) + t.defaults
532 for a,d in zip(t.args, defaults):
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000533 if first:first = False
534 else: self.write(", ")
535 self.dispatch(a),
Mark Dickinson20379132010-06-30 14:19:56 +0000536 if d:
537 self.write("=")
538 self.dispatch(d)
539
540 # varargs
Tim Peters400cbc32006-02-28 18:44:41 +0000541 if t.vararg:
542 if first:first = False
543 else: self.write(", ")
Mark Dickinson20379132010-06-30 14:19:56 +0000544 self.write("*")
545 self.write(t.vararg)
546
547 # kwargs
Tim Peters400cbc32006-02-28 18:44:41 +0000548 if t.kwarg:
549 if first:first = False
550 else: self.write(", ")
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000551 self.write("**"+t.kwarg)
Tim Peters400cbc32006-02-28 18:44:41 +0000552
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000553 def _keyword(self, t):
554 self.write(t.arg)
555 self.write("=")
556 self.dispatch(t.value)
Tim Peters3daf3042006-04-10 20:28:40 +0000557
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000558 def _Lambda(self, t):
Mark Dickinson20379132010-06-30 14:19:56 +0000559 self.write("(")
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000560 self.write("lambda ")
561 self.dispatch(t.args)
562 self.write(": ")
563 self.dispatch(t.body)
Mark Dickinson20379132010-06-30 14:19:56 +0000564 self.write(")")
Tim Peters3daf3042006-04-10 20:28:40 +0000565
Georg Brandl124df832007-03-19 19:02:48 +0000566 def _alias(self, t):
567 self.write(t.name)
568 if t.asname:
569 self.write(" as "+t.asname)
570
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000571def roundtrip(filename, output=sys.stdout):
Mark Dickinson20379132010-06-30 14:19:56 +0000572 with open(filename, "r") as pyfile:
573 source = pyfile.read()
574 tree = compile(source, filename, "exec", ast.PyCF_ONLY_AST)
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000575 Unparser(tree, output)
Tim Peters400cbc32006-02-28 18:44:41 +0000576
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000577
578
579def testdir(a):
580 try:
581 names = [n for n in os.listdir(a) if n.endswith('.py')]
582 except OSError:
Mark Dickinson20379132010-06-30 14:19:56 +0000583 sys.stderr.write("Directory not readable: %s" % a)
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000584 else:
585 for n in names:
586 fullname = os.path.join(a, n)
587 if os.path.isfile(fullname):
588 output = cStringIO.StringIO()
589 print 'Testing %s' % fullname
590 try:
591 roundtrip(fullname, output)
Mark Dickinson20379132010-06-30 14:19:56 +0000592 except Exception as e:
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000593 print ' Failed to compile, exception is %s' % repr(e)
594 elif os.path.isdir(fullname):
595 testdir(fullname)
596
597def main(args):
598 if args[0] == '--testdir':
599 for a in args[1:]:
600 testdir(a)
601 else:
602 for a in args:
603 roundtrip(a)
Tim Peters3daf3042006-04-10 20:28:40 +0000604
Tim Peters400cbc32006-02-28 18:44:41 +0000605if __name__=='__main__':
Martin v. Löwis3fa6c092006-04-10 12:43:55 +0000606 main(sys.argv[1:])