Advertisement
Guest User

Untitled

a guest
Aug 21st, 2015
237
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 16.30 KB | None | 0 0
  1. import sys
  2. import ast
  3. import tokenize
  4. import io
  5. import os
  6.  
  7. # Large float and imaginary literals get turned into infinities in the AST.
  8. # We unparse those infinities to INFSTR.
  9. INFSTR = "1e" + repr(sys.float_info.max_10_exp + 1)
  10.  
  11. def interleave(inter, f, seq):
  12.     """Call f on each item in seq, calling inter() in between.
  13.    """
  14.     seq = iter(seq)
  15.     try:
  16.         f(next(seq))
  17.     except StopIteration:
  18.         pass
  19.     else:
  20.         for x in seq:
  21.             inter()
  22.             f(x)
  23.  
  24. class Unparser:
  25.     """Methods in this class recursively traverse an AST and
  26.    output source code for the abstract syntax; original formatting
  27.    is disregarded. """
  28.  
  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
  33.         self._indent = 0
  34.         self.dispatch(tree)
  35.         self.f.flush()
  36.  
  37.     def fill(self, text = ""):
  38.         "Indent a piece of text, according to the current indentation level"
  39.         self.f.write("\n"+"    "*self._indent + text)
  40.  
  41.     def write(self, text):
  42.         "Append a piece of text to the current line."
  43.         self.f.write(text)
  44.  
  45.     def enter(self):
  46.         "Print ':', and increase the indentation."
  47.         self.write(":")
  48.         self._indent += 1
  49.  
  50.     def leave(self):
  51.         "Decrease the indentation level."
  52.         self._indent -= 1
  53.  
  54.     def dispatch(self, tree):
  55.         "Dispatcher function, dispatching tree type T to method _T."
  56.         if isinstance(tree, list):
  57.             for t in tree:
  58.                 self.dispatch(t)
  59.             return
  60.         meth = getattr(self, "_"+tree.__class__.__name__)
  61.         meth(tree)
  62.  
  63.  
  64.     ############### Unparsing methods ######################
  65.     # There should be one method per concrete grammar type #
  66.     # Constructors should be grouped by sum type. Ideally, #
  67.     # this would follow the order in the grammar, but      #
  68.     # currently doesn't.                                   #
  69.     ########################################################
  70.  
  71.     def _Module(self, tree):
  72.         for stmt in tree.body:
  73.             self.dispatch(stmt)
  74.  
  75.     # stmt
  76.     def _Expr(self, tree):
  77.         self.fill()
  78.         self.dispatch(tree.value)
  79.  
  80.     def _Import(self, t):
  81.         self.fill("import ")
  82.         interleave(lambda: self.write(", "), self.dispatch, t.names)
  83.  
  84.     def _ImportFrom(self, t):
  85.         self.fill("from ")
  86.         self.write("." * t.level)
  87.         if t.module:
  88.             self.write(t.module)
  89.         self.write(" import ")
  90.         interleave(lambda: self.write(", "), self.dispatch, t.names)
  91.  
  92.     def _Assign(self, t):
  93.         self.fill()
  94.         for target in t.targets:
  95.             self.dispatch(target)
  96.             self.write(" = ")
  97.         self.dispatch(t.value)
  98.  
  99.     def _AugAssign(self, t):
  100.         self.fill()
  101.         self.dispatch(t.target)
  102.         self.write(" "+self.binop[t.op.__class__.__name__]+"= ")
  103.         self.dispatch(t.value)
  104.  
  105.     def _Return(self, t):
  106.         self.fill("return")
  107.         if t.value:
  108.             self.write(" ")
  109.             self.dispatch(t.value)
  110.  
  111.     def _Pass(self, t):
  112.         self.fill("pass")
  113.  
  114.     def _Break(self, t):
  115.         self.fill("break")
  116.  
  117.     def _Continue(self, t):
  118.         self.fill("continue")
  119.  
  120.     def _Delete(self, t):
  121.         self.fill("del ")
  122.         interleave(lambda: self.write(", "), self.dispatch, t.targets)
  123.  
  124.     def _Assert(self, t):
  125.         self.fill("assert ")
  126.         self.dispatch(t.test)
  127.         if t.msg:
  128.             self.write(", ")
  129.             self.dispatch(t.msg)
  130.  
  131.     def _Global(self, t):
  132.         self.fill("global ")
  133.         interleave(lambda: self.write(", "), self.write, t.names)
  134.  
  135.     def _Nonlocal(self, t):
  136.         self.fill("nonlocal ")
  137.         interleave(lambda: self.write(", "), self.write, t.names)
  138.  
  139.     def _Await(self, t):
  140.         self.write("(")
  141.         self.write("await")
  142.         if t.value:
  143.             self.write(" ")
  144.             self.dispatch(t.value)
  145.         self.write(")")
  146.  
  147.     def _Yield(self, t):
  148.         self.write("(")
  149.         self.write("yield")
  150.         if t.value:
  151.             self.write(" ")
  152.             self.dispatch(t.value)
  153.         self.write(")")
  154.  
  155.     def _YieldFrom(self, t):
  156.         self.write("(")
  157.         self.write("yield from")
  158.         if t.value:
  159.             self.write(" ")
  160.             self.dispatch(t.value)
  161.         self.write(")")
  162.  
  163.     def _Raise(self, t):
  164.         self.fill("raise")
  165.         if not t.exc:
  166.             assert not t.cause
  167.             return
  168.         self.write(" ")
  169.         self.dispatch(t.exc)
  170.         if t.cause:
  171.             self.write(" from ")
  172.             self.dispatch(t.cause)
  173.  
  174.     def _Try(self, t):
  175.         self.fill("try")
  176.         self.enter()
  177.         self.dispatch(t.body)
  178.         self.leave()
  179.         for ex in t.handlers:
  180.             self.dispatch(ex)
  181.         if t.orelse:
  182.             self.fill("else")
  183.             self.enter()
  184.             self.dispatch(t.orelse)
  185.             self.leave()
  186.         if t.finalbody:
  187.             self.fill("finally")
  188.             self.enter()
  189.             self.dispatch(t.finalbody)
  190.             self.leave()
  191.  
  192.     def _ExceptHandler(self, t):
  193.         self.fill("except")
  194.         if t.type:
  195.             self.write(" ")
  196.             self.dispatch(t.type)
  197.         if t.name:
  198.             self.write(" as ")
  199.             self.write(t.name)
  200.         self.enter()
  201.         self.dispatch(t.body)
  202.         self.leave()
  203.  
  204.     def _ClassDef(self, t):
  205.         self.write("\n")
  206.         for deco in t.decorator_list:
  207.             self.fill("@")
  208.             self.dispatch(deco)
  209.         self.fill("class "+t.name)
  210.         self.write("(")
  211.         comma = False
  212.         for e in t.bases:
  213.             if comma: self.write(", ")
  214.             else: comma = True
  215.             self.dispatch(e)
  216.         for e in t.keywords:
  217.             if comma: self.write(", ")
  218.             else: comma = True
  219.             self.dispatch(e)
  220.         self.write(")")
  221.  
  222.         self.enter()
  223.         self.dispatch(t.body)
  224.         self.leave()
  225.  
  226.     def _FunctionDef(self, t):
  227.         self.__FunctionDef_helper(t, "def")
  228.  
  229.     def _AsyncFunctionDef(self, t):
  230.         self.__FunctionDef_helper(t, "async def")
  231.  
  232.     def __FunctionDef_helper(self, t, fill_suffix):
  233.         self.write("\n")
  234.         for deco in t.decorator_list:
  235.             self.fill("@")
  236.             self.dispatch(deco)
  237.         def_str = fill_suffix+" "+t.name + "("
  238.         self.fill(def_str)
  239.         self.dispatch(t.args)
  240.         self.write(")")
  241.         if t.returns:
  242.             self.write(" -> ")
  243.             self.dispatch(t.returns)
  244.         self.enter()
  245.         self.dispatch(t.body)
  246.         self.leave()
  247.  
  248.     def _For(self, t):
  249.         self.__For_helper("for ", t)
  250.  
  251.     def _AsyncFor(self, t):
  252.         self.__For_helper("async for ", t)
  253.  
  254.     def __For_helper(self, fill, t):
  255.         self.fill(fill)
  256.         self.dispatch(t.target)
  257.         self.write(" in ")
  258.         self.dispatch(t.iter)
  259.         self.enter()
  260.         self.dispatch(t.body)
  261.         self.leave()
  262.         if t.orelse:
  263.             self.fill("else")
  264.             self.enter()
  265.             self.dispatch(t.orelse)
  266.             self.leave()
  267.  
  268.     def _If(self, t):
  269.         self.fill("if ")
  270.         self.dispatch(t.test)
  271.         self.enter()
  272.         self.dispatch(t.body)
  273.         self.leave()
  274.         # collapse nested ifs into equivalent elifs.
  275.         while (t.orelse and len(t.orelse) == 1 and
  276.                isinstance(t.orelse[0], ast.If)):
  277.             t = t.orelse[0]
  278.             self.fill("elif ")
  279.             self.dispatch(t.test)
  280.             self.enter()
  281.             self.dispatch(t.body)
  282.             self.leave()
  283.         # final else
  284.         if t.orelse:
  285.             self.fill("else")
  286.             self.enter()
  287.             self.dispatch(t.orelse)
  288.             self.leave()
  289.  
  290.     def _While(self, t):
  291.         self.fill("while ")
  292.         self.dispatch(t.test)
  293.         self.enter()
  294.         self.dispatch(t.body)
  295.         self.leave()
  296.         if t.orelse:
  297.             self.fill("else")
  298.             self.enter()
  299.             self.dispatch(t.orelse)
  300.             self.leave()
  301.  
  302.     def _With(self, t):
  303.         self.fill("with ")
  304.         interleave(lambda: self.write(", "), self.dispatch, t.items)
  305.         self.enter()
  306.         self.dispatch(t.body)
  307.         self.leave()
  308.  
  309.     def _AsyncWith(self, t):
  310.         self.fill("async with ")
  311.         interleave(lambda: self.write(", "), self.dispatch, t.items)
  312.         self.enter()
  313.         self.dispatch(t.body)
  314.         self.leave()
  315.  
  316.     # expr
  317.     def _Bytes(self, t):
  318.         self.write(repr(t.s))
  319.  
  320.     def _Str(self, tree):
  321.         self.write(repr(tree.s))
  322.  
  323.     def _Name(self, t):
  324.         self.write(t.id)
  325.  
  326.     def _NameConstant(self, t):
  327.         self.write(repr(t.value))
  328.  
  329.     def _Num(self, t):
  330.         # Substitute overflowing decimal literal for AST infinities.
  331.         self.write(repr(t.n).replace("inf", INFSTR))
  332.  
  333.     def _List(self, t):
  334.         self.write("[")
  335.         interleave(lambda: self.write(", "), self.dispatch, t.elts)
  336.         self.write("]")
  337.  
  338.     def _ListComp(self, t):
  339.         self.write("[")
  340.         self.dispatch(t.elt)
  341.         for gen in t.generators:
  342.             self.dispatch(gen)
  343.         self.write("]")
  344.  
  345.     def _GeneratorExp(self, t):
  346.         self.write("(")
  347.         self.dispatch(t.elt)
  348.         for gen in t.generators:
  349.             self.dispatch(gen)
  350.         self.write(")")
  351.  
  352.     def _SetComp(self, t):
  353.         self.write("{")
  354.         self.dispatch(t.elt)
  355.         for gen in t.generators:
  356.             self.dispatch(gen)
  357.         self.write("}")
  358.  
  359.     def _DictComp(self, t):
  360.         self.write("{")
  361.         self.dispatch(t.key)
  362.         self.write(": ")
  363.         self.dispatch(t.value)
  364.         for gen in t.generators:
  365.             self.dispatch(gen)
  366.         self.write("}")
  367.  
  368.     def _comprehension(self, t):
  369.         self.write(" for ")
  370.         self.dispatch(t.target)
  371.         self.write(" in ")
  372.         self.dispatch(t.iter)
  373.         for if_clause in t.ifs:
  374.             self.write(" if ")
  375.             self.dispatch(if_clause)
  376.  
  377.     def _IfExp(self, t):
  378.         self.write("(")
  379.         self.dispatch(t.body)
  380.         self.write(" if ")
  381.         self.dispatch(t.test)
  382.         self.write(" else ")
  383.         self.dispatch(t.orelse)
  384.         self.write(")")
  385.  
  386.     def _Set(self, t):
  387.         assert(t.elts) # should be at least one element
  388.         self.write("{")
  389.         interleave(lambda: self.write(", "), self.dispatch, t.elts)
  390.         self.write("}")
  391.  
  392.     def _Dict(self, t):
  393.         self.write("{")
  394.         def write_pair(pair):
  395.             (k, v) = pair
  396.             self.dispatch(k)
  397.             self.write(": ")
  398.             self.dispatch(v)
  399.         interleave(lambda: self.write(", "), write_pair, zip(t.keys, t.values))
  400.         self.write("}")
  401.  
  402.     def _Tuple(self, t):
  403.         self.write("(")
  404.         if len(t.elts) == 1:
  405.             (elt,) = t.elts
  406.             self.dispatch(elt)
  407.             self.write(",")
  408.         else:
  409.             interleave(lambda: self.write(", "), self.dispatch, t.elts)
  410.         self.write(")")
  411.  
  412.     unop = {"Invert":"~", "Not": "not", "UAdd":"+", "USub":"-"}
  413.     def _UnaryOp(self, t):
  414.         self.write("(")
  415.         self.write(self.unop[t.op.__class__.__name__])
  416.         self.write(" ")
  417.         self.dispatch(t.operand)
  418.         self.write(")")
  419.  
  420.     binop = { "Add":"+", "Sub":"-", "Mult":"*", "MatMult":"@", "Div":"/", "Mod":"%",
  421.                     "LShift":"<<", "RShift":">>", "BitOr":"|", "BitXor":"^", "BitAnd":"&",
  422.                     "FloorDiv":"//", "Pow": "**"}
  423.     def _BinOp(self, t):
  424.         self.write("(")
  425.         self.dispatch(t.left)
  426.         self.write(" " + self.binop[t.op.__class__.__name__] + " ")
  427.         self.dispatch(t.right)
  428.         self.write(")")
  429.  
  430.     cmpops = {"Eq":"==", "NotEq":"!=", "Lt":"<", "LtE":"<=", "Gt":">", "GtE":">=",
  431.                         "Is":"is", "IsNot":"is not", "In":"in", "NotIn":"not in"}
  432.     def _Compare(self, t):
  433.         self.write("(")
  434.         self.dispatch(t.left)
  435.         for o, e in zip(t.ops, t.comparators):
  436.             self.write(" " + self.cmpops[o.__class__.__name__] + " ")
  437.             self.dispatch(e)
  438.         self.write(")")
  439.  
  440.     boolops = {ast.And: 'and', ast.Or: 'or'}
  441.     def _BoolOp(self, t):
  442.         self.write("(")
  443.         s = " %s " % self.boolops[t.op.__class__]
  444.         interleave(lambda: self.write(s), self.dispatch, t.values)
  445.         self.write(")")
  446.  
  447.     def _Attribute(self,t):
  448.         self.dispatch(t.value)
  449.         # Special case: 3.__abs__() is a syntax error, so if t.value
  450.         # is an integer literal then we need to either parenthesize
  451.         # it or add an extra space to get 3 .__abs__().
  452.         if isinstance(t.value, ast.Num) and isinstance(t.value.n, int):
  453.             self.write(" ")
  454.         self.write(".")
  455.         self.write(t.attr)
  456.  
  457.     def _Call(self, t):
  458.         self.dispatch(t.func)
  459.         self.write("(")
  460.         comma = False
  461.         for e in t.args:
  462.             if comma: self.write(", ")
  463.             else: comma = True
  464.             self.dispatch(e)
  465.         for e in t.keywords:
  466.             if comma: self.write(", ")
  467.             else: comma = True
  468.             self.dispatch(e)
  469.         self.write(")")
  470.  
  471.     def _Subscript(self, t):
  472.         self.dispatch(t.value)
  473.         self.write("[")
  474.         self.dispatch(t.slice)
  475.         self.write("]")
  476.  
  477.     def _Starred(self, t):
  478.         self.write("*")
  479.         self.dispatch(t.value)
  480.  
  481.     # slice
  482.     def _Ellipsis(self, t):
  483.         self.write("...")
  484.  
  485.     def _Index(self, t):
  486.         self.dispatch(t.value)
  487.  
  488.     def _Slice(self, t):
  489.         if t.lower:
  490.             self.dispatch(t.lower)
  491.         self.write(":")
  492.         if t.upper:
  493.             self.dispatch(t.upper)
  494.         if t.step:
  495.             self.write(":")
  496.             self.dispatch(t.step)
  497.  
  498.     def _ExtSlice(self, t):
  499.         interleave(lambda: self.write(', '), self.dispatch, t.dims)
  500.  
  501.     # argument
  502.     def _arg(self, t):
  503.         self.write(t.arg)
  504.         if t.annotation:
  505.             self.write(": ")
  506.             self.dispatch(t.annotation)
  507.  
  508.     # others
  509.     def _arguments(self, t):
  510.         first = True
  511.         # normal arguments
  512.         defaults = [None] * (len(t.args) - len(t.defaults)) + t.defaults
  513.         for a, d in zip(t.args, defaults):
  514.             if first:first = False
  515.             else: self.write(", ")
  516.             self.dispatch(a)
  517.             if d:
  518.                 self.write("=")
  519.                 self.dispatch(d)
  520.  
  521.         # varargs, or bare '*' if no varargs but keyword-only arguments present
  522.         if t.vararg or t.kwonlyargs:
  523.             if first:first = False
  524.             else: self.write(", ")
  525.             self.write("*")
  526.             if t.vararg:
  527.                 self.write(t.vararg.arg)
  528.                 if t.vararg.annotation:
  529.                     self.write(": ")
  530.                     self.dispatch(t.vararg.annotation)
  531.  
  532.         # keyword-only arguments
  533.         if t.kwonlyargs:
  534.             for a, d in zip(t.kwonlyargs, t.kw_defaults):
  535.                 if first:first = False
  536.                 else: self.write(", ")
  537.                 self.dispatch(a),
  538.                 if d:
  539.                     self.write("=")
  540.                     self.dispatch(d)
  541.  
  542.         # kwargs
  543.         if t.kwarg:
  544.             if first:first = False
  545.             else: self.write(", ")
  546.             self.write("**"+t.kwarg.arg)
  547.             if t.kwarg.annotation:
  548.                 self.write(": ")
  549.                 self.dispatch(t.kwarg.annotation)
  550.  
  551.     def _keyword(self, t):
  552.         if t.arg is None:
  553.             self.write("**")
  554.         else:
  555.             self.write(t.arg)
  556.             self.write("=")
  557.         self.dispatch(t.value)
  558.  
  559.     def _Lambda(self, t):
  560.         self.write("(")
  561.         self.write("lambda ")
  562.         self.dispatch(t.args)
  563.         self.write(": ")
  564.         self.dispatch(t.body)
  565.         self.write(")")
  566.  
  567.     def _alias(self, t):
  568.         self.write(t.name)
  569.         if t.asname:
  570.             self.write(" as "+t.asname)
  571.  
  572.     def _withitem(self, t):
  573.         self.dispatch(t.context_expr)
  574.         if t.optional_vars:
  575.             self.write(" as ")
  576.             self.dispatch(t.optional_vars)
  577.  
  578. def roundtrip(tree, output=sys.stdout):
  579.  
  580.     Unparser(tree, output)
  581.  
  582. def main(args):
  583.      roundtrip(args)
  584.  
  585.  
  586. T = ast.parse('a * (b + c)', mode='exec')
  587.  
  588.  
  589. main(T)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement