blob: 3eb63108c5901ef439b59de51da116da9531ea82 [file] [log] [blame]
Tim Peters400cbc32006-02-28 18:44:41 +00001"Usage: unparse.py <path to source file>"
2import sys
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +00003import ast
Mark Dickinson82c8d932010-06-29 07:48:23 +00004import tokenize
Collin Winter6f2df4d2007-07-17 20:59:35 +00005import io
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006import os
Tim Peters400cbc32006-02-28 18:44:41 +00007
Mark Dickinsoncba8c102010-06-30 11:45:53 +00008# Large float and imaginary literals get turned into infinities in the AST.
9# We unparse those infinities to INFSTR.
10INFSTR = "1e" + repr(sys.float_info.max_10_exp + 1)
11
Guido van Rossumd8faa362007-04-27 19:54:29 +000012def interleave(inter, f, seq):
13 """Call f on each item in seq, calling inter() in between.
14 """
15 seq = iter(seq)
16 try:
Collin Winter6f2df4d2007-07-17 20:59:35 +000017 f(next(seq))
Guido van Rossumd8faa362007-04-27 19:54:29 +000018 except StopIteration:
19 pass
20 else:
21 for x in seq:
22 inter()
23 f(x)
24
Tim Peters400cbc32006-02-28 18:44:41 +000025class Unparser:
26 """Methods in this class recursively traverse an AST and
27 output source code for the abstract syntax; original formatting
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +000028 is disregarded. """
Tim Peters400cbc32006-02-28 18:44:41 +000029
30 def __init__(self, tree, file = sys.stdout):
31 """Unparser(tree, file=sys.stdout) -> None.
32 Print the source for tree to file."""
33 self.f = file
34 self._indent = 0
35 self.dispatch(tree)
Collin Winter6f2df4d2007-07-17 20:59:35 +000036 print("", file=self.f)
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):
INADA Naokicb41b272017-02-23 00:31:59 +090074 if tree.docstring is not None:
75 self.fill(repr(tree.docstring))
Tim Peters400cbc32006-02-28 18:44:41 +000076 for stmt in tree.body:
77 self.dispatch(stmt)
78
79 # stmt
80 def _Expr(self, tree):
81 self.fill()
82 self.dispatch(tree.value)
83
84 def _Import(self, t):
85 self.fill("import ")
Guido van Rossumd8faa362007-04-27 19:54:29 +000086 interleave(lambda: self.write(", "), self.dispatch, t.names)
Tim Peters400cbc32006-02-28 18:44:41 +000087
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000088 def _ImportFrom(self, t):
89 self.fill("from ")
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +000090 self.write("." * t.level)
91 if t.module:
92 self.write(t.module)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000093 self.write(" import ")
Guido van Rossumd8faa362007-04-27 19:54:29 +000094 interleave(lambda: self.write(", "), self.dispatch, t.names)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000095
Tim Peters400cbc32006-02-28 18:44:41 +000096 def _Assign(self, t):
97 self.fill()
98 for target in t.targets:
99 self.dispatch(target)
100 self.write(" = ")
101 self.dispatch(t.value)
102
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000103 def _AugAssign(self, t):
104 self.fill()
105 self.dispatch(t.target)
106 self.write(" "+self.binop[t.op.__class__.__name__]+"= ")
107 self.dispatch(t.value)
108
Yury Selivanovf8cb8a12016-09-08 20:50:03 -0700109 def _AnnAssign(self, t):
110 self.fill()
111 if not t.simple and isinstance(t.target, ast.Name):
112 self.write('(')
113 self.dispatch(t.target)
114 if not t.simple and isinstance(t.target, ast.Name):
115 self.write(')')
116 self.write(": ")
117 self.dispatch(t.annotation)
118 if t.value:
119 self.write(" = ")
120 self.dispatch(t.value)
121
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000122 def _Return(self, t):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000123 self.fill("return")
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000124 if t.value:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000125 self.write(" ")
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000126 self.dispatch(t.value)
127
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000128 def _Pass(self, t):
129 self.fill("pass")
130
131 def _Break(self, t):
132 self.fill("break")
133
134 def _Continue(self, t):
135 self.fill("continue")
136
137 def _Delete(self, t):
138 self.fill("del ")
Mark Dickinsonae100052010-06-28 19:44:20 +0000139 interleave(lambda: self.write(", "), self.dispatch, t.targets)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000140
141 def _Assert(self, t):
142 self.fill("assert ")
143 self.dispatch(t.test)
144 if t.msg:
145 self.write(", ")
146 self.dispatch(t.msg)
147
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000148 def _Global(self, t):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000149 self.fill("global ")
150 interleave(lambda: self.write(", "), self.write, t.names)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000151
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +0000152 def _Nonlocal(self, t):
153 self.fill("nonlocal ")
154 interleave(lambda: self.write(", "), self.write, t.names)
155
Yury Selivanov75445082015-05-11 22:57:16 -0400156 def _Await(self, t):
157 self.write("(")
158 self.write("await")
159 if t.value:
160 self.write(" ")
161 self.dispatch(t.value)
162 self.write(")")
163
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000164 def _Yield(self, t):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000165 self.write("(")
166 self.write("yield")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000167 if t.value:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000168 self.write(" ")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000169 self.dispatch(t.value)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000170 self.write(")")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000171
Mark Dickinsonfe8440a2012-05-06 17:35:19 +0100172 def _YieldFrom(self, t):
173 self.write("(")
174 self.write("yield from")
175 if t.value:
176 self.write(" ")
177 self.dispatch(t.value)
178 self.write(")")
179
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000180 def _Raise(self, t):
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +0000181 self.fill("raise")
182 if not t.exc:
183 assert not t.cause
184 return
185 self.write(" ")
186 self.dispatch(t.exc)
187 if t.cause:
188 self.write(" from ")
189 self.dispatch(t.cause)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000190
Mark Dickinsonfe8440a2012-05-06 17:35:19 +0100191 def _Try(self, t):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000192 self.fill("try")
193 self.enter()
194 self.dispatch(t.body)
195 self.leave()
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000196 for ex in t.handlers:
197 self.dispatch(ex)
198 if t.orelse:
199 self.fill("else")
200 self.enter()
201 self.dispatch(t.orelse)
202 self.leave()
Mark Dickinsonfe8440a2012-05-06 17:35:19 +0100203 if t.finalbody:
204 self.fill("finally")
Mark Dickinson81ad8cc2010-06-30 08:46:53 +0000205 self.enter()
Mark Dickinsonfe8440a2012-05-06 17:35:19 +0100206 self.dispatch(t.finalbody)
Mark Dickinson81ad8cc2010-06-30 08:46:53 +0000207 self.leave()
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000208
Benjamin Petersonc4fe6f32008-08-19 18:57:56 +0000209 def _ExceptHandler(self, t):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000210 self.fill("except")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000211 if t.type:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000212 self.write(" ")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000213 self.dispatch(t.type)
214 if t.name:
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +0000215 self.write(" as ")
216 self.write(t.name)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000217 self.enter()
218 self.dispatch(t.body)
219 self.leave()
220
Tim Peters400cbc32006-02-28 18:44:41 +0000221 def _ClassDef(self, t):
222 self.write("\n")
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +0000223 for deco in t.decorator_list:
224 self.fill("@")
225 self.dispatch(deco)
Tim Peters400cbc32006-02-28 18:44:41 +0000226 self.fill("class "+t.name)
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +0000227 self.write("(")
228 comma = False
229 for e in t.bases:
230 if comma: self.write(", ")
231 else: comma = True
232 self.dispatch(e)
233 for e in t.keywords:
234 if comma: self.write(", ")
235 else: comma = True
236 self.dispatch(e)
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +0000237 self.write(")")
238
Tim Peters400cbc32006-02-28 18:44:41 +0000239 self.enter()
INADA Naokicb41b272017-02-23 00:31:59 +0900240 if t.docstring is not None:
241 self.fill(repr(t.docstring))
Tim Peters400cbc32006-02-28 18:44:41 +0000242 self.dispatch(t.body)
243 self.leave()
244
245 def _FunctionDef(self, t):
Yury Selivanov75445082015-05-11 22:57:16 -0400246 self.__FunctionDef_helper(t, "def")
247
248 def _AsyncFunctionDef(self, t):
249 self.__FunctionDef_helper(t, "async def")
250
251 def __FunctionDef_helper(self, t, fill_suffix):
Tim Peters400cbc32006-02-28 18:44:41 +0000252 self.write("\n")
Benjamin Petersonc4fe6f32008-08-19 18:57:56 +0000253 for deco in t.decorator_list:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000254 self.fill("@")
255 self.dispatch(deco)
Yury Selivanov75445082015-05-11 22:57:16 -0400256 def_str = fill_suffix+" "+t.name + "("
257 self.fill(def_str)
Tim Peters400cbc32006-02-28 18:44:41 +0000258 self.dispatch(t.args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000259 self.write(")")
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +0000260 if t.returns:
261 self.write(" -> ")
262 self.dispatch(t.returns)
Tim Peters400cbc32006-02-28 18:44:41 +0000263 self.enter()
INADA Naokicb41b272017-02-23 00:31:59 +0900264 if t.docstring is not None:
265 self.fill(repr(t.docstring))
Tim Peters400cbc32006-02-28 18:44:41 +0000266 self.dispatch(t.body)
267 self.leave()
268
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000269 def _For(self, t):
Yury Selivanov75445082015-05-11 22:57:16 -0400270 self.__For_helper("for ", t)
271
272 def _AsyncFor(self, t):
273 self.__For_helper("async for ", t)
274
275 def __For_helper(self, fill, t):
276 self.fill(fill)
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000277 self.dispatch(t.target)
278 self.write(" in ")
279 self.dispatch(t.iter)
280 self.enter()
281 self.dispatch(t.body)
282 self.leave()
283 if t.orelse:
284 self.fill("else")
285 self.enter()
286 self.dispatch(t.orelse)
Mark Dickinsonae100052010-06-28 19:44:20 +0000287 self.leave()
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000288
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000289 def _If(self, t):
290 self.fill("if ")
291 self.dispatch(t.test)
292 self.enter()
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000293 self.dispatch(t.body)
294 self.leave()
Mark Dickinson8d6d7602010-06-30 08:32:11 +0000295 # collapse nested ifs into equivalent elifs.
296 while (t.orelse and len(t.orelse) == 1 and
297 isinstance(t.orelse[0], ast.If)):
298 t = t.orelse[0]
299 self.fill("elif ")
300 self.dispatch(t.test)
301 self.enter()
302 self.dispatch(t.body)
303 self.leave()
304 # final else
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000305 if t.orelse:
306 self.fill("else")
307 self.enter()
308 self.dispatch(t.orelse)
309 self.leave()
310
311 def _While(self, t):
312 self.fill("while ")
313 self.dispatch(t.test)
314 self.enter()
315 self.dispatch(t.body)
316 self.leave()
317 if t.orelse:
318 self.fill("else")
319 self.enter()
320 self.dispatch(t.orelse)
Mark Dickinsonae100052010-06-28 19:44:20 +0000321 self.leave()
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000322
323 def _With(self, t):
324 self.fill("with ")
Mark Dickinsonfe8440a2012-05-06 17:35:19 +0100325 interleave(lambda: self.write(", "), self.dispatch, t.items)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000326 self.enter()
327 self.dispatch(t.body)
328 self.leave()
329
Yury Selivanov75445082015-05-11 22:57:16 -0400330 def _AsyncWith(self, t):
331 self.fill("async with ")
332 interleave(lambda: self.write(", "), self.dispatch, t.items)
333 self.enter()
334 self.dispatch(t.body)
335 self.leave()
336
Tim Peters400cbc32006-02-28 18:44:41 +0000337 # expr
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +0000338 def _Bytes(self, t):
339 self.write(repr(t.s))
340
Tim Peters400cbc32006-02-28 18:44:41 +0000341 def _Str(self, tree):
342 self.write(repr(tree.s))
343
Eric V. Smith608adf92015-09-20 15:09:15 -0400344 def _JoinedStr(self, t):
345 self.write("f")
346 string = io.StringIO()
347 self._fstring_JoinedStr(t, string.write)
348 self.write(repr(string.getvalue()))
349
350 def _FormattedValue(self, t):
351 self.write("f")
352 string = io.StringIO()
353 self._fstring_FormattedValue(t, string.write)
354 self.write(repr(string.getvalue()))
355
356 def _fstring_JoinedStr(self, t, write):
357 for value in t.values:
358 meth = getattr(self, "_fstring_" + type(value).__name__)
359 meth(value, write)
360
361 def _fstring_Str(self, t, write):
362 value = t.s.replace("{", "{{").replace("}", "}}")
363 write(value)
364
Victor Stinnerf2c1aa12016-01-26 00:40:57 +0100365 def _fstring_Constant(self, t, write):
366 assert isinstance(t.value, str)
367 value = t.value.replace("{", "{{").replace("}", "}}")
368 write(value)
369
Eric V. Smith608adf92015-09-20 15:09:15 -0400370 def _fstring_FormattedValue(self, t, write):
371 write("{")
372 expr = io.StringIO()
373 Unparser(t.value, expr)
374 expr = expr.getvalue().rstrip("\n")
375 if expr.startswith("{"):
376 write(" ") # Separate pair of opening brackets as "{ {"
377 write(expr)
378 if t.conversion != -1:
379 conversion = chr(t.conversion)
380 assert conversion in "sra"
381 write(f"!{conversion}")
382 if t.format_spec:
383 write(":")
384 meth = getattr(self, "_fstring_" + type(t.format_spec).__name__)
385 meth(t.format_spec, write)
386 write("}")
387
Tim Peters400cbc32006-02-28 18:44:41 +0000388 def _Name(self, t):
389 self.write(t.id)
390
Victor Stinnerf2c1aa12016-01-26 00:40:57 +0100391 def _write_constant(self, value):
392 if isinstance(value, (float, complex)):
393 self.write(repr(value).replace("inf", INFSTR))
394 else:
395 self.write(repr(value))
396
397 def _Constant(self, t):
398 value = t.value
399 if isinstance(value, tuple):
400 self.write("(")
401 if len(value) == 1:
402 self._write_constant(value[0])
403 self.write(",")
404 else:
405 interleave(lambda: self.write(", "), self._write_constant, value)
406 self.write(")")
407 else:
408 self._write_constant(t.value)
409
Benjamin Peterson442f2092012-12-06 17:41:04 -0500410 def _NameConstant(self, t):
411 self.write(repr(t.value))
412
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000413 def _Num(self, t):
Mark Dickinsoncba8c102010-06-30 11:45:53 +0000414 # Substitute overflowing decimal literal for AST infinities.
415 self.write(repr(t.n).replace("inf", INFSTR))
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000416
Tim Peters400cbc32006-02-28 18:44:41 +0000417 def _List(self, t):
418 self.write("[")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000419 interleave(lambda: self.write(", "), self.dispatch, t.elts)
Tim Peters400cbc32006-02-28 18:44:41 +0000420 self.write("]")
421
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000422 def _ListComp(self, t):
423 self.write("[")
424 self.dispatch(t.elt)
425 for gen in t.generators:
426 self.dispatch(gen)
427 self.write("]")
428
429 def _GeneratorExp(self, t):
430 self.write("(")
431 self.dispatch(t.elt)
432 for gen in t.generators:
433 self.dispatch(gen)
434 self.write(")")
435
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +0000436 def _SetComp(self, t):
437 self.write("{")
438 self.dispatch(t.elt)
439 for gen in t.generators:
440 self.dispatch(gen)
441 self.write("}")
442
443 def _DictComp(self, t):
444 self.write("{")
445 self.dispatch(t.key)
446 self.write(": ")
447 self.dispatch(t.value)
448 for gen in t.generators:
449 self.dispatch(gen)
450 self.write("}")
451
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000452 def _comprehension(self, t):
Yury Selivanovbf04b062016-09-09 11:48:39 -0700453 if t.is_async:
454 self.write(" async for ")
455 else:
456 self.write(" for ")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000457 self.dispatch(t.target)
458 self.write(" in ")
459 self.dispatch(t.iter)
460 for if_clause in t.ifs:
461 self.write(" if ")
462 self.dispatch(if_clause)
463
464 def _IfExp(self, t):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000465 self.write("(")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000466 self.dispatch(t.body)
467 self.write(" if ")
468 self.dispatch(t.test)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000469 self.write(" else ")
470 self.dispatch(t.orelse)
471 self.write(")")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000472
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +0000473 def _Set(self, t):
474 assert(t.elts) # should be at least one element
475 self.write("{")
476 interleave(lambda: self.write(", "), self.dispatch, t.elts)
477 self.write("}")
478
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000479 def _Dict(self, t):
480 self.write("{")
Berker Peksagd66dd5c2016-03-06 16:50:15 +0200481 def write_key_value_pair(k, v):
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000482 self.dispatch(k)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000483 self.write(": ")
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000484 self.dispatch(v)
Berker Peksagd66dd5c2016-03-06 16:50:15 +0200485
486 def write_item(item):
487 k, v = item
488 if k is None:
489 # for dictionary unpacking operator in dicts {**{'y': 2}}
490 # see PEP 448 for details
491 self.write("**")
492 self.dispatch(v)
493 else:
494 write_key_value_pair(k, v)
495 interleave(lambda: self.write(", "), write_item, zip(t.keys, t.values))
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000496 self.write("}")
497
498 def _Tuple(self, t):
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000499 self.write("(")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000500 if len(t.elts) == 1:
Victor Stinnerf2c1aa12016-01-26 00:40:57 +0100501 elt = t.elts[0]
Guido van Rossumd8faa362007-04-27 19:54:29 +0000502 self.dispatch(elt)
503 self.write(",")
504 else:
505 interleave(lambda: self.write(", "), self.dispatch, t.elts)
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000506 self.write(")")
507
Tim Peters400cbc32006-02-28 18:44:41 +0000508 unop = {"Invert":"~", "Not": "not", "UAdd":"+", "USub":"-"}
509 def _UnaryOp(self, t):
Tim Peters400cbc32006-02-28 18:44:41 +0000510 self.write("(")
Mark Dickinsonae100052010-06-28 19:44:20 +0000511 self.write(self.unop[t.op.__class__.__name__])
512 self.write(" ")
Tim Peters400cbc32006-02-28 18:44:41 +0000513 self.dispatch(t.operand)
514 self.write(")")
515
Benjamin Peterson63c46b22014-04-10 00:17:48 -0400516 binop = { "Add":"+", "Sub":"-", "Mult":"*", "MatMult":"@", "Div":"/", "Mod":"%",
Mark Dickinsonae100052010-06-28 19:44:20 +0000517 "LShift":"<<", "RShift":">>", "BitOr":"|", "BitXor":"^", "BitAnd":"&",
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000518 "FloorDiv":"//", "Pow": "**"}
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000519 def _BinOp(self, t):
520 self.write("(")
521 self.dispatch(t.left)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000522 self.write(" " + self.binop[t.op.__class__.__name__] + " ")
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000523 self.dispatch(t.right)
524 self.write(")")
525
526 cmpops = {"Eq":"==", "NotEq":"!=", "Lt":"<", "LtE":"<=", "Gt":">", "GtE":">=",
527 "Is":"is", "IsNot":"is not", "In":"in", "NotIn":"not in"}
528 def _Compare(self, t):
529 self.write("(")
530 self.dispatch(t.left)
531 for o, e in zip(t.ops, t.comparators):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000532 self.write(" " + self.cmpops[o.__class__.__name__] + " ")
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000533 self.dispatch(e)
Mark Dickinsonf5451e52010-06-28 20:09:18 +0000534 self.write(")")
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000535
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +0000536 boolops = {ast.And: 'and', ast.Or: 'or'}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000537 def _BoolOp(self, t):
538 self.write("(")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000539 s = " %s " % self.boolops[t.op.__class__]
540 interleave(lambda: self.write(s), self.dispatch, t.values)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000541 self.write(")")
542
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000543 def _Attribute(self,t):
544 self.dispatch(t.value)
Mark Dickinsonb67e15c2010-06-30 09:05:47 +0000545 # Special case: 3.__abs__() is a syntax error, so if t.value
546 # is an integer literal then we need to either parenthesize
547 # it or add an extra space to get 3 .__abs__().
Victor Stinnerf2c1aa12016-01-26 00:40:57 +0100548 if ((isinstance(t.value, ast.Num) and isinstance(t.value.n, int))
549 or (isinstance(t.value, ast.Constant) and isinstance(t.value.value, int))):
Mark Dickinsonb67e15c2010-06-30 09:05:47 +0000550 self.write(" ")
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000551 self.write(".")
552 self.write(t.attr)
553
554 def _Call(self, t):
555 self.dispatch(t.func)
556 self.write("(")
557 comma = False
558 for e in t.args:
559 if comma: self.write(", ")
560 else: comma = True
561 self.dispatch(e)
562 for e in t.keywords:
563 if comma: self.write(", ")
564 else: comma = True
565 self.dispatch(e)
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000566 self.write(")")
567
568 def _Subscript(self, t):
569 self.dispatch(t.value)
570 self.write("[")
571 self.dispatch(t.slice)
572 self.write("]")
573
Mark Dickinson1b2e9442012-05-06 17:27:39 +0100574 def _Starred(self, t):
575 self.write("*")
576 self.dispatch(t.value)
577
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000578 # slice
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000579 def _Ellipsis(self, t):
580 self.write("...")
581
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000582 def _Index(self, t):
583 self.dispatch(t.value)
584
585 def _Slice(self, t):
586 if t.lower:
587 self.dispatch(t.lower)
588 self.write(":")
589 if t.upper:
590 self.dispatch(t.upper)
591 if t.step:
592 self.write(":")
593 self.dispatch(t.step)
594
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000595 def _ExtSlice(self, t):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000596 interleave(lambda: self.write(', '), self.dispatch, t.dims)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000597
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +0000598 # argument
599 def _arg(self, t):
600 self.write(t.arg)
601 if t.annotation:
602 self.write(": ")
603 self.dispatch(t.annotation)
604
Tim Peters400cbc32006-02-28 18:44:41 +0000605 # others
606 def _arguments(self, t):
607 first = True
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +0000608 # normal arguments
609 defaults = [None] * (len(t.args) - len(t.defaults)) + t.defaults
610 for a, d in zip(t.args, defaults):
Tim Peters400cbc32006-02-28 18:44:41 +0000611 if first:first = False
612 else: self.write(", ")
613 self.dispatch(a)
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +0000614 if d:
615 self.write("=")
616 self.dispatch(d)
617
618 # varargs, or bare '*' if no varargs but keyword-only arguments present
619 if t.vararg or t.kwonlyargs:
Martin v. Löwis87a8b4f2006-02-28 21:41:30 +0000620 if first:first = False
621 else: self.write(", ")
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +0000622 self.write("*")
623 if t.vararg:
Benjamin Petersoncda75be2013-03-18 10:48:58 -0700624 self.write(t.vararg.arg)
625 if t.vararg.annotation:
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +0000626 self.write(": ")
Benjamin Petersoncda75be2013-03-18 10:48:58 -0700627 self.dispatch(t.vararg.annotation)
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +0000628
629 # keyword-only arguments
630 if t.kwonlyargs:
631 for a, d in zip(t.kwonlyargs, t.kw_defaults):
632 if first:first = False
633 else: self.write(", ")
634 self.dispatch(a),
635 if d:
636 self.write("=")
637 self.dispatch(d)
638
639 # kwargs
Tim Peters400cbc32006-02-28 18:44:41 +0000640 if t.kwarg:
641 if first:first = False
642 else: self.write(", ")
Benjamin Petersoncda75be2013-03-18 10:48:58 -0700643 self.write("**"+t.kwarg.arg)
644 if t.kwarg.annotation:
Mark Dickinsonfa2e4e92010-06-28 21:14:17 +0000645 self.write(": ")
Benjamin Petersoncda75be2013-03-18 10:48:58 -0700646 self.dispatch(t.kwarg.annotation)
Tim Peters400cbc32006-02-28 18:44:41 +0000647
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000648 def _keyword(self, t):
Benjamin Peterson025e9eb2015-05-05 20:16:41 -0400649 if t.arg is None:
650 self.write("**")
651 else:
652 self.write(t.arg)
653 self.write("=")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000654 self.dispatch(t.value)
655
656 def _Lambda(self, t):
Mark Dickinson8042e282010-06-29 10:01:48 +0000657 self.write("(")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000658 self.write("lambda ")
659 self.dispatch(t.args)
660 self.write(": ")
661 self.dispatch(t.body)
Mark Dickinson8042e282010-06-29 10:01:48 +0000662 self.write(")")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000663
Guido van Rossumd8faa362007-04-27 19:54:29 +0000664 def _alias(self, t):
665 self.write(t.name)
666 if t.asname:
667 self.write(" as "+t.asname)
668
Mark Dickinsonfe8440a2012-05-06 17:35:19 +0100669 def _withitem(self, t):
670 self.dispatch(t.context_expr)
671 if t.optional_vars:
672 self.write(" as ")
673 self.dispatch(t.optional_vars)
674
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000675def roundtrip(filename, output=sys.stdout):
Mark Dickinson82c8d932010-06-29 07:48:23 +0000676 with open(filename, "rb") as pyfile:
677 encoding = tokenize.detect_encoding(pyfile.readline)[0]
678 with open(filename, "r", encoding=encoding) as pyfile:
679 source = pyfile.read()
Mark Dickinson3d1bfbf2010-06-28 21:39:51 +0000680 tree = compile(source, filename, "exec", ast.PyCF_ONLY_AST)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000681 Unparser(tree, output)
682
683
684
685def testdir(a):
686 try:
687 names = [n for n in os.listdir(a) if n.endswith('.py')]
688 except OSError:
Collin Winter6f2df4d2007-07-17 20:59:35 +0000689 print("Directory not readable: %s" % a, file=sys.stderr)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000690 else:
691 for n in names:
692 fullname = os.path.join(a, n)
693 if os.path.isfile(fullname):
Collin Winter6f2df4d2007-07-17 20:59:35 +0000694 output = io.StringIO()
695 print('Testing %s' % fullname)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000696 try:
697 roundtrip(fullname, output)
Guido van Rossumb940e112007-01-10 16:19:56 +0000698 except Exception as e:
Collin Winter6f2df4d2007-07-17 20:59:35 +0000699 print(' Failed to compile, exception is %s' % repr(e))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000700 elif os.path.isdir(fullname):
701 testdir(fullname)
702
703def main(args):
704 if args[0] == '--testdir':
705 for a in args[1:]:
706 testdir(a)
707 else:
708 for a in args:
709 roundtrip(a)
Tim Peters400cbc32006-02-28 18:44:41 +0000710
711if __name__=='__main__':
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000712 main(sys.argv[1:])