Пример #1
0
 def delete_code(self, target):
     if type(target) is ast.Attribute:
         return [
             T('delattr({}, {!r})').format(self.visit(target.value),
                                           target.attr)
         ]
     elif type(target) is ast.Subscript:
         if type(target.slice) is ast.Slice and target.slice.step is None:
             return [
                 T("(lambda o, **t: type('translator', (), {{t[m]: "
                   "staticmethod(object.__getattribute__(d[m], '__get__'"
                   ")(o, type(o))) for d in [object.__getattribute__("
                   "type(o), '__dict__')] for m in t if m in d}})())({},"
                   " __delitem__='__getitem__', __delslice__="
                   "'__getslice__', __len__='__len__')[{}]").format(
                       self.visit(target.value), self.visit(target.slice))
             ]
         else:
             return [
                 T("(lambda o: object.__getattribute__("
                   "object.__getattribute__(type(o), '__dict__')"
                   "['__delitem__'], '__get__')(o, type(o)))"
                   "({})({})").format(self.visit(target.value),
                                      self.slice_repr(target.slice))
             ]
     elif type(target) is ast.Name:
         return [self.delete_var(target.id)]
     elif type(target) in (ast.List, ast.Tuple):
         return [c for elt in target.elts for c in self.delete_code(elt)]
     else:
         raise NotImplementedError('Case not caught: %s' %
                                   str(type(target)))
Пример #2
0
 def visit_FunctionDef(self, tree):
     # self.visit() returns something of the form
     # ('lambda x, y, z=5, *args: ', ['x', 'y', 'z', 'args'])
     args, arg_names = self.visit(tree.args)
     decoration = T('{}')
     for decorator in tree.decorator_list:
         decoration = decoration.format(T('{}({})').format(self.visit(decorator), T('{}')))
     ns = self.next_child()
     body = ns.many_to_one(tree.body)
     if arg_names:
         body = assignment_component(body,
             T(', ').join(ns.var(name) for name in arg_names),
             T(', ').join(arg_names))
     body = self.close(ns, body)
     function_code = args + body
     doc = ast.get_docstring(tree, clean=False)
     if tree.decorator_list:
         return assignment_component(
             T('{after}'),
             self.store_var(tree.name),
             decoration.format(assignment_component(
                 '__func',
                 '__func, __func.__name__' + ('' if doc is None else ', __func.__doc__'),
                 T('{}, {!r}' + ('' if doc is None else ', {!r}')).format(
                     function_code, tree.name, doc))))
     else:
         return assignment_component(
             T('{after}'),
             T('{}, {}.__name__' + ('' if doc is None else ', {}.__doc__')).format(
                 self.store_var(tree.name), self.var(tree.name), self.var(tree.name)),
             T('{}, {!r}' + ('' if doc is None else ', {!r}')).format(
                 function_code, tree.name, doc))
Пример #3
0
def get_init_code(tree, table):
    # Calculate the helper variables that we will need, wrap the output
    # code in a definition of those variables.

    # TODO: Short-circuit to something far simpler if the program has but one
    # print statement.

    output = Namespace(table).many_to_one(tree.body)

    doc = ast.get_docstring(tree, clean=False)
    if doc is not None:
        output = assignment_component(output, T("{__g}['__doc__']"), repr(doc))

    output = provide(
        output.format(__l=T('{__g}')),
        __print=T("__import__('__builtin__').__dict__['print']"),
        __exec="__import__('trace').Trace(count=False,"
               " trace=False).runctx",
        __y="(lambda f: (lambda x: x(x))(lambda y:"
          " f(lambda: y(y)())))",
        __g=T("globals()"),
        __sys="__import__('sys')",
        __types="__import__('types')")

    return output.close()
Пример #4
0
 def visit_Compare(self, tree):
     assert len(tree.ops) == len(tree.comparators)
     return T('({})').format(
         self.visit(tree.left) + T('').join([
             cmpop_code[type(tree.ops[i])] + self.visit(tree.comparators[i])
             for i in range(len(tree.ops))
         ]))
Пример #5
0
 def visit_Assign(self, tree):
     targets = [self.visit(target) for target in tree.targets]
     value = self.visit(tree.value)
     targets = T(', ').join(targets)
     return assignment_component(T('{after}'), targets,
         value if len(tree.targets) == 1
               else T('[{}]*{}').format(value, len(tree.targets)))
Пример #6
0
def get_init_code(tree, table):
    """Get one-lined code from `tree` and `table.

    Calculate the helper variables that we will need, and wrap the output
    code (computed from `tree`) with definitions of those variables.

    TODO: Short-circuit to something far simpler if the program has only one
    print statement.

    Arguments:
        tree: Python AST node
        table: symtable.symtable

    Returns:
        string - valid one-line code
    """
    output = Namespace(table).many_to_one(tree.body)

    doc = ast.get_docstring(tree, clean=False)
    if doc is not None:
        output = assignment_component(output, T("{__g}['__doc__']"), repr(doc))

    output = provide(output.format(__l=T('{__g}')),
                     __print=T("__import__('__builtin__').__dict__['print']"),
                     __y="(lambda f: (lambda x: x(x))(lambda y:"
                     " f(lambda: y(y)())))",
                     __g=T("globals()"),
                     __contextlib="__import__('contextlib')",
                     __sys="__import__('sys')",
                     __types="__import__('types')")

    return output.close()
Пример #7
0
 def close(self, ns, body, **subs):
     return provide(
         body,
         __l='{}',
         __f=T('{{{}}}').format(T(', ').join(
             T('{!r}: lambda: {}').format(v, self.var(v)) for v in ns.table.get_frees())),
         **subs)
Пример #8
0
 def visit_While(self, tree):
     test = self.visit(tree.test)
     body = self.many_to_one(tree.body, after='__this()')
     orelse = self.many_to_one(tree.orelse, after='__after()')
     return lambda_function({'__after': T('lambda: {after}')}).format(
         T('{__y}(lambda __this: lambda: {} if {} else {})()').format(
             provide(body, __break='__after', __continue='__this'),
             test, orelse))
Пример #9
0
 def visit_Raise(self, tree):
     if tree.type is None:
         return T('([] for [] in []).throw(*{__sys}.exc_info())')
     else:
         return T('([] for [] in []).throw({}{}{})').format(
             self.visit(tree.type),
             '' if tree.inst is None else ', ' + self.visit(tree.inst),
             '' if tree.tback is None else ', ' + self.visit(tree.tback))
Пример #10
0
 def visit_Lambda(self, tree):
     args, arg_names = self.visit(tree.args)
     ns = self.next_child()
     body = ns.visit(tree.body)
     if arg_names:
         body = assignment_component(body, T(', ').join(ns.store_var(name)
             for name in arg_names), T(', ').join(arg_names))
     body = self.close(ns, body)
     return '(' + args + body + ')'
Пример #11
0
def lambda_function(arguments_to_values, prettyprinted=False):
    # arguments_to_values :: {argument_i: value_i}
    # :: string
    if prettyprinted:
        raise NotImplementedError
    else:
        return T('(lambda {}: {})({})').format(
            T(', ').join(arguments_to_values.keys()), T('{}'),
            T(', ').join(arguments_to_values.values()))
Пример #12
0
 def comprehension_code(self, generators, wrap):
     iter0 = self.visit(generators[0].iter)
     ns = self.next_child()
     return self.close(
         ns,
         wrap(ns, T(' ').join(
             [T('for {} in {__iter}').format(ns.visit(generators[0].target))] +
             ['if ' + ns.visit(i) for i in generators[0].ifs] +
             map(ns.visit, generators[1:]))),
         __iter=iter0)
Пример #13
0
    def visit_TryFinally(self, tree):
        body = self.many_to_one(
            tree.body, after=T('(lambda after: after())')).format(
                pre_return=T('(lambda ret: lambda after: ret)({pre_return}'),
                post_return=T('{post_return})'))

        finalbody = self.many_to_one(tree.finalbody, after=T('{after}'))
        if 'pre_return' in finalbody.free():
            finalbody = T('({})(lambda ret: {})').format(
                finalbody.format(
                    after='lambda change_ret: False',
                    pre_return=
                    T('(lambda ret: lambda change_ret: change_ret(ret))({pre_return}'
                      ),
                    post_return=T('{post_return})')),
                assignment_component('True', '__out[0]', 'lambda after: ret'))
        else:
            finalbody = finalbody.format(after='False')

        return \
            lambda_function({'__out': '[None]'}).format(
                lambda_function({
                    '__ctx': T(
                        "{__contextlib}.nested(type('except', (), {{"
                        "'__enter__': lambda self: None, "
                        "'__exit__': lambda __self, __exctype, __value, __traceback: "
                        "{finalbody}}})(), "
                        "type('try', (), {{"
                        "'__enter__': lambda self: None, "
                        "'__exit__': lambda __self, __exctype, __value, __traceback: "
                        "{body}}})())").format(
                            body=assignment_component('False', '__out[0]', body),
                            finalbody=finalbody)
                }).format(
                    T('[__ctx.__enter__(), __ctx.__exit__(None, None, None), __out[0](lambda: {after})][2]')))
Пример #14
0
 def var(self, name):
     name = self.mangle(name)
     sym = self.table.lookup(name)
     if sym.is_global() or (self.table.get_type() == 'module' and sym.is_local()):
         return T('{}').format(name)
     elif sym.is_local():
         return T('{__l}[{!r}]').format(name)
     elif sym.is_free():
         return T('{__f}[{!r}]()').format(name)
     else:
         raise SyntaxError('confusing symbol {!r}'.format(name))
Пример #15
0
 def visit_Print(self, tree):
     to_print = T('{}')
     if tree.dest is not None:
         # Abuse varargs to get the right evaluation order
         to_print = T('file={}, *[{}]').format(self.visit(tree.dest), to_print)
     to_print = to_print.format(T(', ').join(self.visit(x) for x in tree.values))
     if not tree.nl:
         # TODO: This is apparently good enough for 2to3, but gets
         # many cases wrong (tests/unimplemented/softspace.py).
         to_print += ", end=' '"
     return T('({__print}({}), {after})[1]').format(to_print)
Пример #16
0
 def visit_ImportFrom(self, tree):
     return T('(lambda __mod: {})(__import__({!r}, {__g}, {__l},'
              ' {!r}, {!r}))').format(
         assignment_component(
             T('{after}'),
             T(', ').join(self.store_var(alias.name if alias.asname is None
                                         else alias.asname) for alias in tree.names),
             T(', ').join('__mod.' + alias.name for alias in tree.names)),
         '' if tree.module is None else tree.module,
         tuple(alias.name for alias in tree.names),
         tree.level)
Пример #17
0
def lambda_function(arguments_to_values):
    """
    Arguments:
        arguments_to_values: {string: string | T} - e.g. {'a': '47'}

    Returns:
        T - e.g. (lambda a: {})(47)
    """
    return T('(lambda {}: {})({})').format(
        T(', ').join(arguments_to_values.keys()), T('{}'),
        T(', ').join(arguments_to_values.values()))
Пример #18
0
 def delete_var(self, name):
     name = self.mangle(name)
     sym = self.table.lookup(name)
     if sym.is_global():
         return T('{__g}.pop({!r})').format(name)
     elif sym.is_local():
         return T('{__l}.pop({!r})').format(name)
     elif sym.is_free():
         raise SyntaxError('deleting free variable {!r}'.format(name))
     else:
         raise SyntaxError('confusing symbol {!r}'.format(name))
Пример #19
0
 def visit_Import(self, tree):
     after = T('{after}')
     for alias in tree.names:
         ids = alias.name.split('.')
         if alias.asname is None:
             after = assignment_component(after, self.store_var(ids[0]),
                 T('__import__({!r}, {__g}, {__l})').format(alias.name))
         else:
             after = assignment_component(after, self.store_var(alias.asname),
                 T('.').join([T('__import__({!r}, {__g}, {__l})').format(
                     alias.name)] + ids[1:]))
     return after
Пример #20
0
 def visit_ClassDef(self, tree):
     bases = (T(', ').join(map(self.visit, tree.bases)) + ',' *
              (len(tree.bases) == 1))
     decoration = T('{}')
     for decorator in tree.decorator_list:
         decoration = decoration.format(
             T('{}({})').format(self.visit(decorator), T('{}')))
     ns = self.next_child()
     body = ns.many_to_one(tree.body, after=T('{__l}'))
     doc = ast.get_docstring(tree, clean=False)
     body = self.close(
         ns, "{{'__module__': __name__{}}}".format(
             '' if doc is None else ", '__doc__': {!r}".format(doc)), body)
     if tree.bases:
         class_code = T(
             "(lambda b, d: d.get('__metaclass__', getattr(b[0], "
             "'__class__', type(b[0])))({!r}, b, d))(({}), "
             "{})").format(tree.name, bases, body)
     else:
         class_code = T("(lambda d: d.get('__metaclass__', {__g}.get("
                        "'__metaclass__', {__types}.ClassType))({!r}, (), "
                        "d))({})").format(tree.name, body)
     class_code = decoration.format(class_code)
     return assignment_component(T('{after}'), self.store_var(tree.name),
                                 class_code)
Пример #21
0
 def visit_For(self, tree):
     item = self.visit(tree.target)
     items = self.visit(tree.iter)
     body = self.many_to_one(tree.body, after='__this()')
     orelse = self.many_to_one(tree.orelse, after='__after()')
     return lambda_function({'__items': T('iter({})').format(items), '__sentinel':
                             '[]', '__after': T('lambda: {after}')}).format(
         T('{__y}(lambda __this: lambda: {})()').format(
             lambda_function({'__i': 'next(__items, __sentinel)'}).format(
                 T('{} if __i is not __sentinel else {}').format(
                     provide(
                         assignment_component(body, item, '__i'),
                         __break='__after', __continue='__this'),
                     orelse))))
Пример #22
0
 def slice_repr(self, slice):
     if type(slice) is ast.Ellipsis:
         return T('Ellipsis')
     elif type(slice) is ast.Slice:
         return T('slice({}, {}, {})').format(
             'None' if slice.lower is None else self.visit(slice.lower),
             'None' if slice.upper is None else self.visit(slice.upper),
             'None' if slice.step is None else self.visit(slice.step))
     elif type(slice) is ast.ExtSlice:
         return T('({})').format(T(', ').join(map(self.slice_repr, slice.dims)) +
                                 ','*(len(slice.dims) == 1))
     elif type(slice) is ast.Index:
         return self.visit(slice.value)
     else:
         raise NotImplementedError('Case not caught: %s' % str(type(slice)))
Пример #23
0
 def visit_Call(self, tree):
     func = self.visit(tree.func)
     args = [self.visit(arg) for arg in tree.args]
     keywords = [self.visit(kw) for kw in tree.keywords]
     if tree.starargs is None:
         starargs = []
     else:
         starargs = ["*" + self.visit(tree.starargs)]
     if tree.kwargs is None:
         kwargs = []
     else:
         kwargs = ["**" + self.visit(tree.kwargs)]
     elems = args + keywords + starargs + kwargs
     comma_sep_elems = T(', ').join(elems)
     return T('{}({})').format(func, comma_sep_elems)
Пример #24
0
 def visit_Exec(self, tree):
     body = self.visit(tree.body)
     if tree.globals is None:
         exec_code = T('{__exec}({}, {__g}, {__l})').format(body)
     elif tree.locals is None:
         exec_code = T(
             '(lambda b, g: {__exec}(b, {__g} if g is None else g, '
             '{__l} if g is None else g))({}, {})').format(
                 body, self.visit(tree.globals))
     else:
         exec_code = T(
             '(lambda b, g, l: {__exec}(b, {__g} if g is None else g, '
             '({__l} if g is None else g) if l is None else l))({}, {}, {})'
         ).format(body, self.visit(tree.globals), self.visit(tree.locals))
     return T('({}, {after})[1]').format(exec_code)
Пример #25
0
 def many_to_one(self, trees, after='None'):
     # trees :: [Tree]
     # return :: string
     return reduce(
         lambda ctx, tree: ctx.format(after=self.visit(tree)),
         trees,
         T('{after}')).format(after=after)
Пример #26
0
 def var(self, name):
     name = self.mangle(name)
     sym = self.table.lookup(name)
     if self.table.get_type() == 'module' or (
             sym.is_global()
             and self.table.is_optimized()) or name == 'None':
         return T('{}').format(name)
     elif sym.is_global():
         return T('({__l}[{!r}] if {!r} in __l else {})').format(
             name, name, name)
     elif sym.is_local():
         return T('{__l}[{!r}]').format(name)
     elif sym.is_free():
         return T('{___f_' + name + '}()').format(name)
     else:
         raise SyntaxError('confusing symbol {!r}'.format(name))
Пример #27
0
 def visit_arguments(self, tree):
     # this should return something of the form
     # ('lambda x, y, z=5, *args: ', ['x', 'y', 'z', 'args'])
     padded_defaults = [None] * (len(tree.args) -
                                 len(tree.defaults)) + tree.defaults
     arg_names = [arg.id for arg in tree.args]
     args = zip(padded_defaults, tree.args)
     args = [a.id if d is None else a.id + "=" + self.visit(d) for (d, a) in args]
     if tree.vararg is not None:
         args += ["*" + tree.vararg]
         arg_names += [tree.vararg]
     if tree.kwarg is not None:
         args += ["**" + tree.kwarg]
         arg_names += [tree.kwarg]
     args = T(', ').join(args)
     return (T('lambda {}: ').format(args), arg_names)
Пример #28
0
 def close(self, ns, local, body, **subs):
     if self.table.get_type() == 'function':
         subs = dict(
             subs, **{
                 '___f_' + v: T('lambda: {}').format(self.var(v))
                 for v in self.table.get_locals()
             })
     return provide(body, __l=local, **subs)
Пример #29
0
def provide(body, **subs):
    body = T('{}').format(body)
    needed = set(body.free()).intersection(subs)
    if needed:
        return lambda_function({k: subs[k] for k in needed}).format(
            body.format(**{k: k for k in needed}))
    else:
        return body
Пример #30
0
 def visit_Exec(self, tree):
     body = self.visit(tree.body)
     if tree.globals is None and self.table.get_type() == 'module':
         exec_code = T("eval(compile({}, '<string>', 'exec'), "
                       "None, {__l})").format(body)
     elif tree.globals is None:
         exec_code = T(
             "(lambda b, c: (eval(compile(b, '<string>', 'exec'), "
             "None, c), {__l}.update(c)))({}, {__l}.copy())").format(body)
     elif tree.locals is None and self.table.get_type() == 'module':
         exec_code = T(
             "(lambda b, g: eval(compile(b, '<string>', 'exec'), g, "
             "{__l} if g is None else g))({}, {})").format(
                 body, self.visit(tree.globals))
     elif tree.locals is None:
         exec_code = T(
             "(lambda b, g, c: (eval(compile(b, '<string>', 'exec'), g, "
             "c if g is None else g), "
             "{__l}.update(c)))({}, {}, {__l}.copy())").format(
                 body, self.visit(tree.globals))
     elif self.table.get_type() == 'module':
         exec_code = T(
             "(lambda b, g, l: eval(compile(b, '<string>', 'exec'), g, "
             "({__l} if g is None else g) if l is None "
             "else l))({}, {}, {})").format(body, self.visit(tree.globals),
                                            self.visit(tree.locals))
     else:
         exec_code = T(
             "(lambda b, g, l, c: (eval(compile(b, '<string>', 'exec'), g, "
             "(c if g is None else g) if l is None else l), "
             "{__l}.update(c)))({}, {}, {}, {__l}.copy())").format(
                 body, self.visit(tree.globals), self.visit(tree.locals))
     return T('({}, {after})[1]').format(exec_code)