def test_expr_generate(self): """test the round trip of expressions to AST back to python source""" x = 1 y = 2 class F(object): def bar(self, a,b): return a + b def lala(arg): return "blah" + arg local_dict = dict(x=x, y=y, foo=F(), lala=lala) code = "str((x+7*y) / foo.bar(5,6)) + lala('ho')" astnode = pyparser.parse(code) newcode = pyparser.ExpressionGenerator(astnode).value() eq_(eval(code, local_dict), eval(newcode, local_dict)) a = ["one", "two", "three"] hoho = {'somevalue': "asdf"} g = [1, 2, 3, 4, 5] local_dict = dict(a=a, hoho=hoho, g=g) code = "a[2] + hoho['somevalue'] + "\ "repr(g[3:5]) + repr(g[3:]) + repr(g[:5])" astnode = pyparser.parse(code) newcode = pyparser.ExpressionGenerator(astnode).value() eq_(eval(code, local_dict), eval(newcode, local_dict)) local_dict = {'f': lambda: 9, 'x': 7} code = "x+f()" astnode = pyparser.parse(code) newcode = pyparser.ExpressionGenerator(astnode).value() eq_(eval(code, local_dict), eval(newcode, local_dict)) for code in ["repr({'x':7,'y':18})", "repr([])", "repr({})", "repr([{3:[]}])", "repr({'x':37*2 + len([6,7,8])})", "repr([1, 2, {}, {'x':'7'}])", "repr({'x':-1})", "repr(((1,2,3), (4,5,6)))", "repr(1 and 2 and 3 and 4)", "repr(True and False or 55)", "repr(1 & 2 | 3)", "repr(3//5)", "repr(3^5)", "repr([q.endswith('e') for q in " "['one', 'two', 'three']])", "repr([x for x in (5,6,7) if x == 6])", "repr(not False)"]: local_dict = {} astnode = pyparser.parse(code) newcode = pyparser.ExpressionGenerator(astnode).value() eq_(eval(code, local_dict), eval(newcode, local_dict) )
def get_argument_expressions(self, as_call=False): """Return the argument declarations of this FunctionDecl as a printable list. By default the return value is appropriate for writing in a ``def``; set `as_call` to true to build arguments to be passed to the function instead (assuming locals with the same names as the arguments exist). """ namedecls = [] # Build in reverse order, since defaults and slurpy args come last argnames = self.argnames[::-1] kwargnames = self.kwargnames[::-1] defaults = self.defaults[::-1] kwdefaults = self.kwdefaults[::-1] # Named arguments if self.kwargs: namedecls.append("**" + kwargnames.pop(0)) for name in kwargnames: # Keyword-only arguments must always be used by name, so even if # this is a call, print out `foo=foo` if as_call: namedecls.append("%s=%s" % (name, name)) elif kwdefaults: default = kwdefaults.pop(0) if default is None: # The AST always gives kwargs a default, since you can do # `def foo(*, a=1, b, c=3)` namedecls.append(name) else: namedecls.append( "%s=%s" % (name, pyparser.ExpressionGenerator(default).value()) ) else: namedecls.append(name) # Positional arguments if self.varargs: namedecls.append("*" + argnames.pop(0)) for name in argnames: if as_call or not defaults: namedecls.append(name) else: default = defaults.pop(0) namedecls.append( "%s=%s" % (name, pyparser.ExpressionGenerator(default).value()) ) namedecls.reverse() return namedecls
def get_argument_expressions(self, include_defaults=True): """return the argument declarations of this FunctionDecl as a printable list.""" namedecls = [] defaults = [d for d in self.defaults] kwargs = self.kwargs varargs = self.varargs argnames = [f for f in self.argnames] argnames.reverse() for arg in argnames: default = None if kwargs: arg = "**" + arg kwargs = False elif varargs: arg = "*" + arg varargs = False else: default = len(defaults) and defaults.pop() or None if include_defaults and default: namedecls.insert( 0, "%s=%s" % (arg, pyparser.ExpressionGenerator(default).value())) else: namedecls.insert(0, arg) return namedecls