Exemplo n.º 1
0
def fix_block(body, returns=True, prints=False):
    # if not isinstance(body[0], ast.Global):
    body.insert(0, ast.Global(names=['it']))
    # body.insert(1, kast.setter(name('it'),kast.none))
    last_statement = body[-1]
    if isinstance(last_statement, list) and len(last_statement) == 1:
        last_statement = last_statement[0]
        print("HOW??")
    if not isinstance(
            last_statement,
        (ast.Assign, ast.If, nodes.FunctionDef, ast.Return, ast.Assert)):
        if isinstance(last_statement, kast.Print):
            body[-1] = (assign("it", last_statement.values[0]))
            last_statement.values[0] = name("it")
            body.append(last_statement)
        else:
            body[-1] = (assign("it", last_statement))
    if isinstance(last_statement, ast.Assign):
        if not "it" in [x.id for x in last_statement.targets]:
            last_statement.targets.append(Name(id="it", ctx=Store()))
    if returns and not isinstance(body[-1], ast.Return):
        body.append(ast.Return(name("it")))
    # if prints:
    # 	if py3:pass#body.append(kast.call("print", name("it")))
    # else:body.append(Print(dest=None, values=[name("it")], nl=True))  # call symbolically!
    return body
Exemplo n.º 2
0
def _build_thunk(node: ast.Module, fn_cls: Type, globals: Dict, locals: Dict):
    # Temporarily polluting the `locals` scope with the thunk function is not
    # ideal, but choosing an illegal name means that only very sneaky code will
    # be aware of it.
    thunkname = '-aeval-' + ''.join(random.sample(string.hexdigits, 8))

    global_names = exposed_names_with_store(node)
    if global_names:
        node.body.insert(0, ast.Global(list(global_names)))

    if len(node.body) > 0 and isinstance(node.body[-1], ast.Expr):
        node.body[-1] = ast.Return(value=node.body[-1].value)

    node = RewriteExposedAnnotatedNames().visit(node)

    mod = ast.parse('')
    mod.body = [
        fn_cls(
            name=thunkname,
            args=_EMPTY_ARGS,
            body=node.body,
            decorator_list=[],
            returns=None,
        )
    ]
    ast.fix_missing_locations(mod)
    exec(compile(mod, '<string>', 'exec'), globals, locals)
    thunk = locals[thunkname]
    thunk.__name__ = 'aeval_thunk'
    del locals[thunkname]
    return thunk
Exemplo n.º 3
0
    def visit_FunctionDef(self, node):
        # Pre-hook.
        pre_hook_expr = ast.Expr(value=ast.Call(
            func=ast.Name(id='start', ctx=ast.Load()), args=[], keywords=[]))
        # Post-hook.
        finalbody = [
            ast.Global(names=[self._result_id]),
            ast.Assign(targets=[ast.Name(id=self._result_id, ctx=ast.Store())],
                       value=ast.Call(func=ast.Name(id='take_snapshot',
                                                    ctx=ast.Load()),
                                      args=[],
                                      keywords=[])),
            ast.Expr(value=ast.Call(func=ast.Name(id='stop', ctx=ast.Load()),
                                    args=[],
                                    keywords=[]))
        ]

        body_elems = [pre_hook_expr]
        body_elems.extend([elem for elem in node.body])
        node.body.clear()
        node.body.append(
            ast.Try(body=body_elems,
                    handlers=[],
                    orelse=[],
                    finalbody=finalbody))

        return ast.fix_missing_locations(node)
Exemplo n.º 4
0
def p_global_stmt(p):
    '''global_stmt : TAG_GLOBAL namelist'''

    p[0] = ast.Global(names=p[2],
                      lineno=p.get_item(1).lineno,
                      col_offset=p.get_item(1).lexpos)

    return
 def visit_Global(self, node):
     self.generic_visit(node)
     obf_name = self.__obfuscate_name(node, 'name')
     if obf_name:
         return ast.Global(
             names=obf_name
         )
     return node
Exemplo n.º 6
0
def create_function_def(name,
                        localization,
                        decorators,
                        context,
                        line=0,
                        column=0):
    """
    Creates a FunctionDef node, that represent a function declaration. This is used in type inference code, so every
    created function has the following parameters (type_of_self, localization, *varargs, **kwargs) for methods and
    (localization, *varargs, **kwargs) for functions.

    :param name: Name of the function
    :param localization: Localization parameter
    :param decorators: Decorators of the function, mainly the norecursion one
    :param context: Context passed to this method
    :param line: Line
    :param column: Column
    :return: An AST FunctionDef node
    """
    function_def_arguments = ast.arguments()
    function_def_arguments.args = [localization]

    isconstructor = is_constructor(name)
    ismethod = is_method(context, decorators)

    function_def = ast.FunctionDef()
    function_def.lineno = line
    function_def.col_offset = column
    if types.type_inspection.is_special_name_method(name):
        function_def.name = types.type_inspection.convert_special_name_method(
            name)
    else:
        function_def.name = name

    function_def.args = function_def_arguments

    function_def_arguments.args = []

    if isconstructor or (ismethod and not isconstructor):
        function_def_arguments.args.append(
            core_language.create_Name('type_of_self'))

    function_def_arguments.args.append(localization)

    function_def_arguments.kwarg = "kwargs"
    function_def_arguments.vararg = "varargs"
    function_def_arguments.defaults = []

    if data_structures.is_iterable(decorators):
        function_def.decorator_list = decorators
    else:
        function_def.decorator_list = [decorators]

    global_ts = ast.Global()
    global_ts.names = [stypy_functions.default_module_type_store_var_name]
    function_def.body = [global_ts]

    return function_def
Exemplo n.º 7
0
class TestParse(unittest.TestCase):
    def test_parse(self):
        for i, test in enumerate(self.tests):
            with self.subTest(test=i):
                result = parse(test.input)
                expected = ast.fix_missing_locations(test.output)
                self.assertEqual(ast.dump(result, include_attributes=True),
                                 ast.dump(expected, include_attributes=True))

    tests = [
        TestIO(input="x = 5",
               output=ast.Module(body=[
                   ast.Assign(targets=[ast.Name(ctx=ast.Store(), id="x")],
                              value=ast.Num(n=5, col_offset=4))
               ])),
        TestIO(input="foobar()",
               output=ast.Module(body=[
                   ast.Expr(col_offset=0,
                            lineno=1,
                            value=ast.Call(col_offset=0,
                                           lineno=1,
                                           func=ast.Name(col_offset=0,
                                                         lineno=1,
                                                         id="foobar",
                                                         ctx=ast.Load()),
                                           args=[],
                                           keywords=[],
                                           starargs=None,
                                           kwargs=None))
               ])),
        TestIO(input="global x",
               output=ast.Module(
                   body=[ast.Global(names=["x"], lineno=1, col_offset=0)])),
        TestIO(
            input="def function(*, x): pass",
            output=ast.Module(body=[
                ast.FunctionDef(name="function",
                                args=ast.arguments(args=[],
                                                   vararg=None,
                                                   kwonlyargs=[
                                                       ast.arg(arg="x",
                                                               annotation=None,
                                                               lineno=1,
                                                               col_offset=16)
                                                   ],
                                                   kw_defaults=[None],
                                                   kwarg=None,
                                                   defaults=[]),
                                body=[ast.Pass(lineno=1, col_offset=20)],
                                decorator_list=[],
                                returns=None,
                                lineno=1,
                                col_offset=0)
            ]))
    ]
Exemplo n.º 8
0
def compile_restricted_function(
        p,  # parameters
        body,
        name,
        filename='<string>',
        globalize=None,  # List of globals (e.g. ['here', 'context', ...])
        flags=0,
        dont_inherit=False,
        policy=RestrictingNodeTransformer):
    """Compile a restricted code object for a function.

    Documentation see:
    http://restrictedpython.readthedocs.io/en/latest/usage/index.html#RestrictedPython.compile_restricted_function
    """
    # Parse the parameters and body, then combine them.
    try:
        body_ast = ast.parse(body, '<func code>', 'exec')
    except SyntaxError as v:
        error = syntax_error_template.format(
            lineno=v.lineno,
            type=v.__class__.__name__,
            msg=v.msg,
            statement=v.text.strip() if v.text else None)
        return CompileResult(code=None,
                             errors=(error, ),
                             warnings=(),
                             used_names=())

    # The compiled code is actually executed inside a function
    # (that is called when the code is called) so reading and assigning to a
    # global variable like this`printed += 'foo'` would throw an
    # UnboundLocalError.
    # We don't want the user to need to understand this.
    if globalize:
        body_ast.body.insert(0, ast.Global(globalize))
    wrapper_ast = ast.parse('def masked_function_name(%s): pass' % p,
                            '<func wrapper>', 'exec')
    # In case the name you chose for your generated function is not a
    # valid python identifier we set it after the fact
    function_ast = wrapper_ast.body[0]
    assert isinstance(function_ast, ast.FunctionDef)
    function_ast.name = name

    wrapper_ast.body[0].body = body_ast.body
    wrapper_ast = ast.fix_missing_locations(wrapper_ast)

    result = _compile_restricted_mode(wrapper_ast,
                                      filename=filename,
                                      mode='exec',
                                      flags=flags,
                                      dont_inherit=dont_inherit,
                                      policy=policy)

    return result
Exemplo n.º 9
0
    def visit_FunctionDef(self, n):

        old_globals = self.globals

        try:
            n = self.generic_visit(n)

            new_globals = list(self.globals)
            new_globals.sort()

            if new_globals:
                n.body.insert(0, ast.Global(names=new_globals)) # type: ignore

            return n
        finally:
            self.globals = old_globals
Exemplo n.º 10
0
    def cache(self, filename: str = 'module.py') -> None:
        """ Generate and save a modified AST """
        # Generate the AST
        with open(filename, 'r') as f:
            example = f.read()
        tree = ast.parse(example)

        # Add internal caching
        SmartCache._modify_ast(tree)

        # Make all functions global so we can eval
        globals_line = ast.Global(
            names=[RESULT_KEY] +
            [f.name for f in tree.body if isinstance(f, ast.FunctionDef)],
            lineno=1,
            col_offset=0)
        tree.body.insert(0, globals_line)
        self.n_lines = len(example.split('\n'))
        self.tree = tree
Exemplo n.º 11
0
 def test_destructure(self):
     assert self.run([
         ast.Assign([ast_store('test2')],
                    ast_call(
                        ast.FunctionDef('', ast.arguments(
                            [], None, None, []), [
                                ast.Global(['test1']),
                                ast.Assign([
                                    ast.List([
                                        ast_store('test1'),
                                        ast_store('test2'),
                                    ], ast.Store())
                                ],
                                           ast.List([
                                               ast.Str('test1'),
                                               ast.Str('test2'),
                                           ], ast.Load())),
                                ast.Return(ast_load('test2'))
                            ], [])))
     ], 'test1 + "+" + test2') == 'test1+test2'
Exemplo n.º 12
0
 def parse(self):
     """
     Convert the parsed tokens into a list of expressions then join them
     """
     tokens = lexers.sl.lex(self.source)
     state = ParserState()
     klass = parsers.sp.parse(tokens, state)
     body = [
         klass,
         ast.Global(names=['rendered']),
         ast.Assign(targets=[ast.Name(id='rendered', ctx=ast.Store())],
                    value=build_str_join(
                        build_call(
                            ast.Attribute(value=build_call(
                                ast.Name(id='Template', ctx=ast.Load())),
                                          attr='root',
                                          ctx=ast.Load()),
                            args=[ast.Name(id='context', ctx=ast.Load())],
                        )))
     ]
     return ast.Module(body=body)
Exemplo n.º 13
0
    def test_simple_statements(self):
        # Simple statements can be put on a single line as long as the scope
        # has not changed.
        for body, expect in [
            (ast.Expr(ast.Num(42)), '42'),
            (ast.Import([ast.alias('a', None)]), 'import a'),
            (ast.ImportFrom('b', [ast.alias('a', None)],
                            1), 'from .b import a'),
            (ast.Break(), 'break'),
            (ast.Continue(), 'continue'),
            (ast.Pass(), 'pass'),
            (ast.Assign([ast.Name('X', ast.Store())], ast.Num(42)), 'X=42'),
            (ast.Delete([ast.Name('X', ast.Del())]), 'del X'),
            (ast.Raise(None, None), 'raise'),
            (ast.Return(None), 'return'),
            (ast.AugAssign(ast.Name('X', ast.Store()), ast.Add(),
                           ast.Num(42)), 'X+=42'),
            (ast.Assert(ast.Num(42), None), 'assert 42'),
            (ast.Global(['x']), 'global x'),
            (ast.Nonlocal(['x']), 'nonlocal x'),
        ]:
            if_simple = ast.If(ast.Num(42), [body], None)
            self.verify(if_simple, 'if 42:{}'.format(expect))

        if_multiple_simples = ast.If(ast.Num(42),
                                     [ast.Pass(), ast.Pass()], None)
        self.verify(if_multiple_simples, 'if 42:pass;pass')
        inner_if = ast.If(ast.Num(6), [ast.Pass()], None)
        funky_if = ast.If(ast.Num(42), [
            ast.Break(),
            ast.Continue(), inner_if,
            ast.Break(),
            ast.Continue()
        ], None)
        self.verify(funky_if,
                    'if 42:\n break;continue\n if 6:pass\n break;continue')
Exemplo n.º 14
0
 def 全局(各名称, 片段):
     return ast.Global(各名称, lineno=语法树.取行号(片段), col_offset=语法树.取列号(片段))
Exemplo n.º 15
0
 def test_Global(self):
     glbl = ast.Global(['x'])
     self.verify(glbl, 'global x')
     many_glbl = ast.Global(['x', 'y'])
     self.verify(many_glbl, 'global x,y')
Exemplo n.º 16
0
 def test_global(self):
     self.stmt(ast.Global([]), "empty names on Global")
Exemplo n.º 17
0
 def visit_Nonlocal(self, node):
     new_node = ast.copy_location(ast.Global(names=node.names), node)
     return FunctionBodyTransformer.decorate(new_node, node)
Exemplo n.º 18
0
    def test_empty_init(self):
        # Jython 2.5.0 did not allow empty constructors for many ast node types
        # but CPython ast nodes do allow this.  For the moment, I don't see a
        # reason to allow construction of the super types (like ast.AST and
        # ast.stmt) as well as the op types that are implemented as enums in
        # Jython (like boolop), but I've left them in but commented out for
        # now.  We may need them in the future since CPython allows this, but
        # it may fall under implementation detail.

        #ast.AST()
        ast.Add()
        ast.And()
        ast.Assert()
        ast.Assign()
        ast.Attribute()
        ast.AugAssign()
        ast.AugLoad()
        ast.AugStore()
        ast.BinOp()
        ast.BitAnd()
        ast.BitOr()
        ast.BitXor()
        ast.BoolOp()
        ast.Break()
        ast.Call()
        ast.ClassDef()
        ast.Compare()
        ast.Continue()
        ast.Del()
        ast.Delete()
        ast.Dict()
        ast.Div()
        ast.Ellipsis()
        ast.Eq()
        ast.Exec()
        ast.Expr()
        ast.Expression()
        ast.ExtSlice()
        ast.FloorDiv()
        ast.For()
        ast.FunctionDef()
        ast.GeneratorExp()
        ast.Global()
        ast.Gt()
        ast.GtE()
        ast.If()
        ast.IfExp()
        ast.Import()
        ast.ImportFrom()
        ast.In()
        ast.Index()
        ast.Interactive()
        ast.Invert()
        ast.Is()
        ast.IsNot()
        ast.LShift()
        ast.Lambda()
        ast.List()
        ast.ListComp()
        ast.Load()
        ast.Lt()
        ast.LtE()
        ast.Mod()
        ast.Module()
        ast.Mult()
        ast.Name()
        ast.Not()
        ast.NotEq()
        ast.NotIn()
        ast.Num()
        ast.Or()
        ast.Param()
        ast.Pass()
        ast.Pow()
        ast.Print()
        ast.RShift()
        ast.Raise()
        ast.Repr()
        ast.Return()
        ast.Slice()
        ast.Store()
        ast.Str()
        ast.Sub()
        ast.Subscript()
        ast.Suite()
        ast.TryExcept()
        ast.TryFinally()
        ast.Tuple()
        ast.UAdd()
        ast.USub()
        ast.UnaryOp()
        ast.While()
        ast.With()
        ast.Yield()
        ast.alias()
        ast.arguments()
        #ast.boolop()
        #ast.cmpop()
        ast.comprehension()
        #ast.excepthandler()
        #ast.expr()
        #ast.expr_context()
        ast.keyword()
Exemplo n.º 19
0
class TestExportJson(unittest.TestCase):
    maxDiff = None

    def test_export_json(self):
        for i, test in enumerate(self.tests):
            with self.subTest(test=i):
                result = json.loads(export_json(test.input))
                expected = test.output
                self.assertEqual(result, expected)

    tests = [
        TestIO(
            input = ast.Module(
                body = [
                    ast.Assign(
                        targets = [
                            ast.Name(
                                ctx = ast.Store(),
                                id = "x"
                            )
                        ],
                        value = ast.Num(n = 5)
                    )
                ]
            ),
            output = {
                "ast_type": "Module",
                "body": [
                    {
                        "ast_type": "Assign",
                        "col_offset": None,
                        "lineno": None,
                        "targets": [
                            {
                                "ast_type": "Name",
                                "col_offset": None,
                                "ctx": {
                                    "ast_type": "Store"
                                },
                                "id": "x",
                                "lineno": None
                            }
                        ],
                        "value": {
                            "ast_type": "Num",
                            "col_offset": None,
                            "lineno": None,
                            "n": {
                                "ast_type": "int",
                                "n": 5
                            }
                        }
                    }
                ]
            }
        ),
        TestIO(
            input = ast.Module(
                body = [
                    ast.Expr(
                        col_offset = 0,
                        lineno = 1,
                        value = ast.Call(
                            col_offset = 0,
                            lineno = 1,
                            func = ast.Name(
                                col_offset = 0,
                                lineno = 1,
                                id = "foobar",
                                ctx = ast.Load()
                            ),
                            args = [],
                            keywords = [],
                            starargs = None,
                            kwargs = None
                        )
                    )
                ]
            ),
            output = {
                "ast_type": "Module",
                "body": [
                    {
                        "ast_type": "Expr",
                        "col_offset": 0,
                        "lineno": 1,
                        "value": {
                            "args": [],
                            "ast_type": "Call",
                            "col_offset": 0,
                            "func": {
                                "ast_type": "Name",
                                "col_offset": 0,
                                "ctx": {
                                    "ast_type": "Load"
                                },
                                "id": "foobar",
                                "lineno": 1
                            },
                            "keywords": [],
                            "lineno": 1
                        }
                    }
                ]
            }
        ),
        TestIO(
            input = ast.NameConstant(None),
            output = {
                "ast_type": "NameConstant",
                "col_offset": None,
                "lineno": None,
                "value": "None"
            }
        ),
        TestIO(
            input = ast.NameConstant(True),
            output = {
                "ast_type": "NameConstant",
                "col_offset": None,
                "lineno": None,
                "value": "True"
            }
        ),
        TestIO(
            input = ast.NameConstant(False),
            output = {
                "ast_type": "NameConstant",
                "col_offset": None,
                "lineno": None,
                "value": "False"
            }
        ),
        TestIO(
            input = ast.Module(
                body = [
                    ast.Global(
                        names = ["x"],
                        lineno = 1,
                        col_offset = 0
                    )
                ]
            ),
            output = {
                "body": [
                    {
                        "lineno": 1,
                        "col_offset": 0,
                        "ast_type": "Global",
                        "names": ["x"]
                    }
                ],
                "ast_type": "Module"
            }
        ),
        TestIO(
            input = ast.FunctionDef(
                name = "function",
                args = ast.arguments(
                    args = [],
                    vararg = None,
                    kwonlyargs = [
                        ast.arg(
                            arg = "x",
                            annotation = None,
                            lineno = 1,
                            col_offset = 16
                        )
                    ],
                    kw_defaults = [None],
                    kwarg = None,
                    defaults = []
                ),
                body = [
                    ast.Pass(lineno = 1, col_offset = 20)
                ],
                decorator_list = [],
                returns = None,
                lineno = 1,
                col_offset = 0
            ),
            output = {
                "args": {
                    "args": [],
                    "ast_type": "arguments",
                    "defaults": [],
                    "kw_defaults": [None],
                    "kwarg": None,
                    "kwonlyargs": [
                        {
                            "annotation": None,
                            "arg": "x",
                            "ast_type": "arg",
                            "col_offset": 16,
                            "lineno": 1
                        }
                    ],
                    "vararg": None
                },
                "ast_type": "FunctionDef",
                "body": [
                    {
                        "ast_type": "Pass",
                        "col_offset": 20,
                        "lineno": 1
                    }
                ],
                "col_offset": 0,
                "decorator_list": [],
                "lineno": 1,
                "name": "function",
                "returns": None
            }
        )
    ]
Exemplo n.º 20
0
 def compile_global_expression(self, expr):
     expr.pop(0)  # global
     e = expr.pop(0)
     return ast.Global(names=[ast_str(e)],
                       lineno=e.start_line,
                       col_offset=e.start_column)
Exemplo n.º 21
0
class PHP2Python(object):
    def __init__(self):
        self.scope_stack = []

    def get_static(self, name):
        for scope in reversed(self.scope_stack):
            v = scope.statics.get(name)
            if v:
                return v
        return False

    def add_static(self, name):
        if len(self.scope_stack) == 0:
            return
        static_name = "static_" + "_".join([scope.name for scope in self.scope_stack] + [name])
        self.scope_stack[-1].statics[name] = static_name

    def from_phpast(self, node):
    if node is None:
            return py.Name('None', py.Load(**pos(node)), **pos(node))

    if isinstance(node, basestring):
        return py.Str(node, **pos(node))

        if isinstance(node, (int, float, long)):
        return py.Num(node, **pos(node))

    if isinstance(node, php.Array):
        if node.nodes:
            if node.nodes[0].key is not None:
                keys = []
                values = []
                for elem in node.nodes:
                        keys.append(self.from_phpast(elem.key))
                        values.append(self.from_phpast(elem.value))
                    ds = py.Dict(keys, values, **pos(node))
            else:
                    ds = py.List([self.from_phpast(x.value) for x in node.nodes],
                               py.Load(**pos(node)),
                               **pos(node))
        else:
                ds = py.List([], py.Load(**pos(node)), **pos(node))
            return py.Call(py.Name('PHPArray', py.Load(**pos(node)), **pos(node)),
                           [ds],
                           [], None, None, **pos(node))

    if isinstance(node, php.InlineHTML):
        args = [py.Str(node.data, **pos(node))]
        return py.Call(py.Name('inline_html',
                               py.Load(**pos(node)),
                               **pos(node)),
                       args, [], None, None,
                       **pos(node))

    if isinstance(node, php.Echo):
        return py.Call(py.Name('echo', py.Load(**pos(node)),
                               **pos(node)),
                           map(self.from_phpast, node.nodes),
                       [], None, None,
                       **pos(node))

    if isinstance(node, php.Print):
            return py.Print(None, [self.from_phpast(node.node)], True, **pos(node))

    if isinstance(node, php.Exit):
        args = []
        if node.expr is not None:
                args.append(self.from_phpast(node.expr))
            return py.Raise(py.Call(py.Name('SystemExit', py.Load(**pos(node)),
                                        **pos(node)),
                                args, [], None, None, **pos(node)),
                        None, None, **pos(node))

    if isinstance(node, php.Return):
            if len(self.scope_stack) > 0:
                # return from function
        if node.node is None:
            return py.Return(None, **pos(node))
        else:
                    return py.Return(self.from_phpast(node.node), **pos(node))
            else:
                # return from script
                args = [self.from_phpast(node.node)]
                return py.Raise(py.Call(py.Name('_GlobalReturn', py.Load(**pos(node)),
                                                **pos(node)),
                                        args, [], None, None, **pos(node)),
                                None, None, **pos(node))

    if isinstance(node, php.Break):
        assert node.node is None, 'level on break not supported'
        return py.Break(**pos(node))

    if isinstance(node, php.Continue):
        assert node.node is None, 'level on continue not supported'
        return py.Continue(**pos(node))

    if isinstance(node, php.Silence):
            return self.from_phpast(node.expr)

    if isinstance(node, php.Block):
            return self.from_phpast(php.If(1, node, [], None, lineno=node.lineno))

    if isinstance(node, php.Unset):
            return py.Delete(map(self.from_phpast, node.nodes), **pos(node))

    if isinstance(node, php.IsSet) and len(node.nodes) == 1:
        if isinstance(node.nodes[0], php.ArrayOffset):
                return py.Compare(self.from_phpast(node.nodes[0].expr),
                              [py.In(**pos(node))],
                                  [self.from_phpast(node.nodes[0].node)],
                              **pos(node))
        if isinstance(node.nodes[0], php.ObjectProperty):
            return py.Call(py.Name('hasattr', py.Load(**pos(node)),
                                   **pos(node)),
                               [self.from_phpast(node.nodes[0].node),
                                self.from_phpast(node.nodes[0].name)],
                           [], None, None, **pos(node))
        if isinstance(node.nodes[0], php.Variable):
                variable_name = node.nodes[0].name[1:]
                static_name = self.get_static(variable_name)
                if static_name:
                    variable_name = static_name

                globs = py.Call(py.Name('globals', py.Load(**pos(node)),
                                        **pos(node)),
                                [], [], None, None, **pos(node))

                locs = py.Call(py.Name('locals', py.Load(**pos(node)),
                                        **pos(node)),
                                [], [], None, None, **pos(node))

                return py.Compare(py.Str(static_name, **pos(node)),
                              [py.In(**pos(node))],
                                  [py.Call(py.Name('all_vars', py.Load(**pos(node)),
                                               **pos(node)),
                                           [globs, locs], [], None, None, **pos(node))],
                              **pos(node))
            return py.Compare(self.from_phpast(node.nodes[0]),
                          [py.IsNot(**pos(node))],
                          [py.Name('None', py.Load(**pos(node)), **pos(node))],
                          **pos(node))

    if isinstance(node, php.Empty):
            return self.from_phpast(php.UnaryOp('!',
                                       php.BinaryOp('&&',
                                                    php.IsSet([node.expr],
                                                              lineno=node.lineno),
                                                    node.expr,
                                                    lineno=node.lineno),
                                       lineno=node.lineno))

    if isinstance(node, php.Assignment):
        if (isinstance(node.node, php.ArrayOffset)
            and node.node.expr is None):
                return py.Call(py.Attribute(self.from_phpast(node.node.node),
                                        'append', py.Load(**pos(node)),
                                        **pos(node)),
                               [self.from_phpast(node.expr)],
                           [], None, None, **pos(node))
        if (isinstance(node.node, php.ObjectProperty)
            and isinstance(node.node.name, php.BinaryOp)):
            return to_stmt(py.Call(py.Name('setattr', py.Load(**pos(node)),
                                   **pos(node)),
                           [from_phpast(node.node.node),
                            from_phpast(node.node.name),
                            from_phpast(node.expr)],
                           [], None, None, **pos(node)))
        return py.Assign([store(from_phpast(node.node))],
                         from_phpast(node.expr),
                         **pos(node))

    if isinstance(node, php.ListAssignment):
            return py.Assign([py.Tuple(map(store, map(self.from_phpast, node.nodes)),
                                   py.Store(**pos(node)),
                                   **pos(node))],
                             self.from_phpast(node.expr),
                          **pos(node))

    if isinstance(node, php.AssignOp):
            return self.from_phpast(php.Assignment(node.left,
                                          php.BinaryOp(node.op[:-1],
                                                       node.left,
                                                       node.right,
                                                       lineno=node.lineno),
                                          False,
                                          lineno=node.lineno))

    if isinstance(node, (php.PreIncDecOp, php.PostIncDecOp)):
            return self.from_phpast(php.Assignment(node.expr,
                                          php.BinaryOp(node.op[0],
                                                       node.expr,
                                                       1,
                                                       lineno=node.lineno),
                                          False,
                                          lineno=node.lineno))

    if isinstance(node, php.ArrayOffset):
            return py.Subscript(self.from_phpast(node.node),
                                py.Index(self.from_phpast(node.expr), **pos(node)),
                            py.Load(**pos(node)),
                            **pos(node))

    if isinstance(node, php.ObjectProperty):
        if isinstance(node.name, (php.Variable, php.BinaryOp)):
            return py.Call(py.Name('getattr', py.Load(**pos(node)),
                                   **pos(node)),
                               [self.from_phpast(node.node),
                                self.from_phpast(node.name)],
                           [], None, None, **pos(node))            
            return py.Attribute(self.from_phpast(node.node),
                            node.name,
                            py.Load(**pos(node)),
                            **pos(node))

    if isinstance(node, php.Constant):
        name = node.name
        if name.lower() == 'true': name = 'True'
        if name.lower() == 'false': name = 'False'
        if name.lower() == 'null': name = 'None'
        return py.Name(name, py.Load(**pos(node)), **pos(node))

    if isinstance(node, php.Variable):
        name = node.name[1:]
            static_name = self.get_static(name)
            if static_name:
                name = static_name
        if name == 'this': name = 'self'
        return py.Name(name, py.Load(**pos(node)), **pos(node))

    if isinstance(node, php.Global):
            return py.Global([self.from_phpast(var).id for var in node.nodes], **pos(node))

    if isinstance(node, php.Include):
        once = py.Name('True' if node.once else 'False',
                       py.Load(**pos(node)),
                       **pos(node))
        return py.Call(py.Name('include', py.Load(**pos(node)),
                               **pos(node)),
                           [self.from_phpast(node.expr), once],
                       [], None, None, **pos(node))

    if isinstance(node, php.Require):
        once = py.Name('True' if node.once else 'False',
                       py.Load(**pos(node)),
                       **pos(node))
        return py.Call(py.Name('require', py.Load(**pos(node)),
                               **pos(node)),
                           [self.from_phpast(node.expr), once],
                       [], None, None, **pos(node))

    if isinstance(node, php.UnaryOp):
        op = unary_ops.get(node.op)
        assert op is not None, "unknown unary operator: '%s'" % node.op
        op = op(**pos(node))
            return py.UnaryOp(op, self.from_phpast(node.expr), **pos(node))
Exemplo n.º 22
0
def from_phpast(node):
    if node is None:
        return py.Pass(**pos(node))

    if isinstance(node, str):
        return py.Str(node, **pos(node))

    if isinstance(node, (int, float)):
        return py.Num(node, **pos(node))

    if isinstance(node, php.Array):
        if node.nodes:
            if node.nodes[0].key is not None:
                keys = []
                values = []
                for elem in node.nodes:
                    keys.append(from_phpast(elem.key))
                    values.append(from_phpast(elem.value))
                return py.Dict(keys, values, **pos(node))
            else:
                return py.List([from_phpast(x.value) for x in node.nodes],
                               py.Load(**pos(node)), **pos(node))
        else:
            return py.List([], py.Load(**pos(node)), **pos(node))

    if isinstance(node, php.InlineHTML):
        args = [py.Str(node.data, **pos(node))]
        return py.Call(
            py.Name('inline_html', py.Load(**pos(node)), **pos(node)), args,
            [], None, None, **pos(node))

    if isinstance(node, php.Echo):
        return py.Call(py.Name('echo', py.Load(**pos(node)), **pos(node)),
                       list(map(from_phpast, node.nodes)), [], None, None,
                       **pos(node))

    if isinstance(node, php.Print):
        return py.Print(None, [from_phpast(node.node)], True, **pos(node))

    if isinstance(node, php.Exit):
        args = []
        if node.expr is not None:
            args.append(from_phpast(node.expr))
        return py.Raise(
            py.Call(py.Name('Exit', py.Load(**pos(node)), **pos(node)), args,
                    [], None, None, **pos(node)), None, None, **pos(node))

    if isinstance(node, php.Return):
        if node.node is None:
            return py.Return(None, **pos(node))
        else:
            return py.Return(from_phpast(node.node), **pos(node))

    if isinstance(node, php.Break):
        assert node.node is None, 'level on break not supported'
        return py.Break(**pos(node))

    if isinstance(node, php.Continue):
        assert node.node is None, 'level on continue not supported'
        return py.Continue(**pos(node))

    if isinstance(node, php.Silence):
        return from_phpast(node.expr)

    if isinstance(node, php.Block):
        return from_phpast(php.If(1, node, [], None, lineno=node.lineno))

    if isinstance(node, php.Unset):
        return py.Delete(list(map(from_phpast, node.nodes)), **pos(node))

    if isinstance(node, php.IsSet) and len(node.nodes) == 1:
        if isinstance(node.nodes[0], php.ArrayOffset):
            return py.Compare(from_phpast(node.nodes[0].expr),
                              [py.In(**pos(node))],
                              [from_phpast(node.nodes[0].node)], **pos(node))
        if isinstance(node.nodes[0], php.ObjectProperty):
            return py.Call(
                py.Name('hasattr', py.Load(**pos(node)), **pos(node)), [
                    from_phpast(node.nodes[0].node),
                    from_phpast(node.nodes[0].name)
                ], [], None, None, **pos(node))
        if isinstance(node.nodes[0], php.Variable):
            return py.Compare(py.Str(
                node.nodes[0].name[1:], **pos(node)), [py.In(**pos(node))], [
                    py.Call(py.Name('vars', py.Load(**pos(node)), **pos(node)),
                            [], [], None, None, **pos(node))
                ], **pos(node))
        return py.Compare(from_phpast(node.nodes[0]), [py.IsNot(**pos(node))],
                          [py.Name('None', py.Load(**pos(node)), **pos(node))],
                          **pos(node))

    if isinstance(node, php.Empty):
        return from_phpast(
            php.UnaryOp('!',
                        php.BinaryOp('&&',
                                     php.IsSet([node.expr],
                                               lineno=node.lineno),
                                     node.expr,
                                     lineno=node.lineno),
                        lineno=node.lineno))

    if isinstance(node, php.Assignment):
        if (isinstance(node.node, php.ArrayOffset) and node.node.expr is None):
            return py.Call(
                py.Attribute(from_phpast(node.node.node), 'append',
                             py.Load(**pos(node)), **pos(node)),
                [from_phpast(node.expr)], [], None, None, **pos(node))
        if (isinstance(node.node, php.ObjectProperty)
                and isinstance(node.node.name, php.BinaryOp)):
            return to_stmt(
                py.Call(py.Name('setattr', py.Load(**pos(node)), **pos(node)),
                        [
                            from_phpast(node.node.node),
                            from_phpast(node.node.name),
                            from_phpast(node.expr)
                        ], [], None, None, **pos(node)))
        return py.Assign([store(from_phpast(node.node))],
                         from_phpast(node.expr), **pos(node))

    if isinstance(node, php.ListAssignment):
        return py.Assign([
            py.Tuple(list(map(store, list(map(from_phpast, node.nodes)))),
                     py.Store(**pos(node)), **pos(node))
        ], from_phpast(node.expr), **pos(node))

    if isinstance(node, php.AssignOp):
        return from_phpast(
            php.Assignment(node.left,
                           php.BinaryOp(node.op[:-1],
                                        node.left,
                                        node.right,
                                        lineno=node.lineno),
                           False,
                           lineno=node.lineno))

    if isinstance(node, (php.PreIncDecOp, php.PostIncDecOp)):
        return from_phpast(
            php.Assignment(node.expr,
                           php.BinaryOp(node.op[0],
                                        node.expr,
                                        1,
                                        lineno=node.lineno),
                           False,
                           lineno=node.lineno))

    if isinstance(node, php.ArrayOffset):
        return py.Subscript(from_phpast(node.node),
                            py.Index(from_phpast(node.expr), **pos(node)),
                            py.Load(**pos(node)), **pos(node))

    if isinstance(node, php.ObjectProperty):
        if isinstance(node.name, (php.Variable, php.BinaryOp)):
            return py.Call(
                py.Name('getattr', py.Load(**pos(node)), **pos(node)),
                [from_phpast(node.node),
                 from_phpast(node.name)], [], None, None, **pos(node))
        return py.Attribute(from_phpast(node.node), node.name,
                            py.Load(**pos(node)), **pos(node))

    if isinstance(node, php.Constant):
        name = node.name
        if name.lower() == 'true': name = 'True'
        if name.lower() == 'false': name = 'False'
        if name.lower() == 'null': name = 'None'
        return py.Name(name, py.Load(**pos(node)), **pos(node))

    if isinstance(node, php.Variable):
        name = node.name[1:]
        if name == 'this': name = 'self'
        return py.Name(name, py.Load(**pos(node)), **pos(node))

    if isinstance(node, php.Global):
        return py.Global([var.name[1:] for var in node.nodes], **pos(node))

    if isinstance(node, php.Include):
        once = py.Name('True' if node.once else 'False', py.Load(**pos(node)),
                       **pos(node))
        return py.Call(py.Name('include', py.Load(**pos(node)), **pos(node)),
                       [from_phpast(node.expr), once], [], None, None,
                       **pos(node))

    if isinstance(node, php.Require):
        once = py.Name('True' if node.once else 'False', py.Load(**pos(node)),
                       **pos(node))
        return py.Call(py.Name('require', py.Load(**pos(node)), **pos(node)),
                       [from_phpast(node.expr), once], [], None, None,
                       **pos(node))

    if isinstance(node, php.UnaryOp):
        op = unary_ops.get(node.op)
        assert op is not None, "unknown unary operator: '%s'" % node.op
        op = op(**pos(node))
        return py.UnaryOp(op, from_phpast(node.expr), **pos(node))

    if isinstance(node, php.BinaryOp):
        if node.op == '.':
            pattern, pieces = build_format(node.left, node.right)
            if pieces:
                return py.BinOp(
                    py.Str(pattern, **pos(node)), py.Mod(**pos(node)),
                    py.Tuple(list(map(from_phpast, pieces)),
                             py.Load(**pos(node)), **pos(node)), **pos(node))
            else:
                return py.Str(pattern % (), **pos(node))
        if node.op in bool_ops:
            op = bool_ops[node.op](**pos(node))
            return py.BoolOp(op,
                             [from_phpast(node.left),
                              from_phpast(node.right)], **pos(node))
        if node.op in cmp_ops:
            op = cmp_ops[node.op](**pos(node))
            return py.Compare(from_phpast(node.left), [op],
                              [from_phpast(node.right)], **pos(node))
        op = binary_ops.get(node.op)
        if node.op == 'instanceof':
            return py.Call(
                func=py.Name(id='isinstance', ctx=py.Load(**pos(node))),
                args=[from_phpast(node.left),
                      from_phpast(node.right)],
                keywords=[],
                starargs=None,
                kwargs=None)
        assert op is not None, "unknown binary operator: '%s'" % node.op
        op = op(**pos(node))
        return py.BinOp(from_phpast(node.left), op, from_phpast(node.right),
                        **pos(node))

    if isinstance(node, php.TernaryOp):
        return py.IfExp(from_phpast(node.expr), from_phpast(node.iftrue),
                        from_phpast(node.iffalse), **pos(node))

    if isinstance(node, php.Cast):
        return py.Call(
            py.Name(casts.get(node.type, node.type), py.Load(**pos(node)),
                    **pos(node)), [from_phpast(node.expr)], [], None, None,
            **pos(node))

    if isinstance(node, php.If):
        orelse = []
        if node.else_:
            for else_ in map(from_phpast, deblock(node.else_.node)):
                orelse.append(to_stmt(else_))
        for elseif in reversed(node.elseifs):
            orelse = [
                py.If(
                    from_phpast(elseif.expr),
                    list(
                        map(to_stmt,
                            list(map(from_phpast, deblock(elseif.node))))),
                    orelse, **pos(node))
            ]
        return py.If(
            from_phpast(node.expr),
            list(map(to_stmt, list(map(from_phpast, deblock(node.node))))),
            orelse, **pos(node))

    if isinstance(node, php.For):
        assert node.test is None or len(node.test) == 1, \
            'only a single test is supported in for-loops'
        return from_phpast(
            php.Block((node.start or []) + [
                php.While(node.test[0] if node.test else 1,
                          php.Block(deblock(node.node) + (node.count or []),
                                    lineno=node.lineno),
                          lineno=node.lineno)
            ],
                      lineno=node.lineno))

    if isinstance(node, php.Foreach):
        if node.keyvar is None:
            target = py.Name(node.valvar.name[1:], py.Store(**pos(node)),
                             **pos(node))
        else:
            target = py.Tuple([
                py.Name(node.keyvar.name[1:], py.Store(**pos(node))),
                py.Name(node.valvar.name[1:], py.Store(**pos(node)))
            ], py.Store(**pos(node)), **pos(node))
        return py.For(
            target, from_phpast(node.expr),
            list(map(to_stmt, list(map(from_phpast, deblock(node.node))))), [],
            **pos(node))

    if isinstance(node, php.While):
        return py.While(
            from_phpast(node.expr),
            list(map(to_stmt, list(map(from_phpast, deblock(node.node))))), [],
            **pos(node))

    if isinstance(node, php.DoWhile):
        condition = php.If(php.UnaryOp('!', node.expr, lineno=node.lineno),
                           php.Break(None, lineno=node.lineno), [],
                           None,
                           lineno=node.lineno)
        return from_phpast(
            php.While(1,
                      php.Block(deblock(node.node) + [condition],
                                lineno=node.lineno),
                      lineno=node.lineno))

    if isinstance(node, php.Try):
        return py.TryExcept(
            list(map(to_stmt, list(map(from_phpast, node.nodes)))), [
                py.ExceptHandler(
                    py.Name(catch.class_, py.Load(**pos(node)), **pos(node)),
                    store(from_phpast(catch.var)),
                    list(map(to_stmt, list(map(from_phpast, catch.nodes)))),
                    **pos(node)) for catch in node.catches
            ], [], **pos(node))

    if isinstance(node, php.Throw):
        return py.Raise(from_phpast(node.node), None, None, **pos(node))

    if isinstance(node, php.Function):
        args = []
        defaults = []
        for param in node.params:
            args.append(
                py.Name(param.name[1:], py.Param(**pos(node)), **pos(node)))
            if param.default is not None:
                defaults.append(from_phpast(param.default))
        body = list(map(to_stmt, list(map(from_phpast, node.nodes))))
        if not body: body = [py.Pass(**pos(node))]
        return py.FunctionDef(node.name,
                              py.arguments(args, None, None, defaults), body,
                              [], **pos(node))

    if isinstance(node, php.Method):
        args = []
        defaults = []
        decorator_list = []
        if 'static' in node.modifiers:
            decorator_list.append(
                py.Name('classmethod', py.Load(**pos(node)), **pos(node)))
            args.append(py.Name('cls', py.Param(**pos(node)), **pos(node)))
        else:
            args.append(py.Name('self', py.Param(**pos(node)), **pos(node)))
        for param in node.params:
            args.append(
                py.Name(param.name[1:], py.Param(**pos(node)), **pos(node)))
            if param.default is not None:
                defaults.append(from_phpast(param.default))
        body = list(map(to_stmt, list(map(from_phpast, node.nodes))))
        if not body: body = [py.Pass(**pos(node))]
        return py.FunctionDef(node.name,
                              py.arguments(args, None, None, defaults), body,
                              decorator_list, **pos(node))

    if isinstance(node, php.Class):
        name = node.name
        bases = []
        extends = node.extends or 'object'
        bases.append(py.Name(extends, py.Load(**pos(node)), **pos(node)))
        body = list(map(to_stmt, list(map(from_phpast, node.nodes))))
        for stmt in body:
            if (isinstance(stmt, py.FunctionDef)
                    and stmt.name in (name, '__construct')):
                stmt.name = '__init__'
        if not body: body = [py.Pass(**pos(node))]
        return py.ClassDef(name, bases, body, [], **pos(node))

    if isinstance(node, (php.ClassConstants, php.ClassVariables)):
        assert len(node.nodes) == 1, \
            'only one class-level assignment supported per line'
        if isinstance(node.nodes[0], php.ClassConstant):
            name = php.Constant(node.nodes[0].name, lineno=node.lineno)
        else:
            name = php.Variable(node.nodes[0].name, lineno=node.lineno)
        initial = node.nodes[0].initial
        if initial is None:
            initial = php.Constant('None', lineno=node.lineno)
        return py.Assign([store(from_phpast(name))], from_phpast(initial),
                         **pos(node))

    if isinstance(node, (php.FunctionCall, php.New)):
        if isinstance(node.name, str):
            name = py.Name(node.name, py.Load(**pos(node)), **pos(node))
        else:
            name = py.Subscript(
                py.Call(py.Name('vars', py.Load(**pos(node)), **pos(node)), [],
                        [], None, None, **pos(node)),
                py.Index(from_phpast(node.name), **pos(node)),
                py.Load(**pos(node)), **pos(node))
        args, kwargs = build_args(node.params)
        return py.Call(name, args, kwargs, None, None, **pos(node))

    if isinstance(node, php.MethodCall):
        args, kwargs = build_args(node.params)
        return py.Call(
            py.Attribute(from_phpast(node.node), node.name,
                         py.Load(**pos(node)), **pos(node)), args, kwargs,
            None, None, **pos(node))

    if isinstance(node, php.StaticMethodCall):
        class_ = node.class_
        if class_ == 'self': class_ = 'cls'
        args, kwargs = build_args(node.params)
        return py.Call(
            py.Attribute(py.Name(class_, py.Load(**pos(node)),
                                 **pos(node)), node.name, py.Load(**pos(node)),
                         **pos(node)), args, kwargs, None, None, **pos(node))

    if isinstance(node, php.StaticProperty):
        class_ = node.node
        name = node.name
        if isinstance(name, php.Variable):
            name = name.name[1:]
        return py.Attribute(py.Name(class_, py.Load(**pos(node)), **pos(node)),
                            name, py.Load(**pos(node)), **pos(node))

    return py.Call(py.Name('XXX', py.Load(**pos(node)),
                           **pos(node)), [py.Str(str(node), **pos(node))], [],
                   None, None, **pos(node))
Exemplo n.º 23
0
def Global(draw) -> ast.Global:
    return ast.Global(draw(lists(name(), min_size=1, max_size=3)))
 def test_token_list(self):
     node = python_ast.Global()
     setattr(node, "names", ["v1", "v2"])
     assert python_ast.dump(node) == \
         python_ast.dump(to_python_ast(to_ast(node, lambda x: [x])))
Exemplo n.º 25
0
 def visit_FunctionDef(self, node):
     node.body.insert(0, ast.Global(names=['_count']))
     return node
Exemplo n.º 26
0
 def visitGlobal(self, n, *args):
     return ast.Global(names=n.names)
    def visit_Global(self, node: Global, *args, **kwargs) -> C.Global:
        names = self.visit(node.names, *args, **kwargs)

        return C.Global(names=names, )
def make_global():
    """Global(identifier* names)"""

    return ast.Global(names=["global_var"])
Exemplo n.º 29
0
def as_ast(dct):
    """See https://docs.python.org/2/library/ast.html"""
    if dct['ast_type'] == "Module":
        return ast.Module(dct["body"])
    elif dct['ast_type'] == "Interactive":
        return ast.Interactive(dct["body"])
    elif dct['ast_type'] == "Expression":
        return ast.Expression(dct["body"])
    elif dct['ast_type'] == "Suite":
        return ast.Suite(dct["body"])
    elif dct['ast_type'] == "FunctionDef":
        return ast.FunctionDef(dct["name"], dct["args"], dct["body"],
                               dct["decorator_list"])
    elif dct['ast_type'] == "ClassDef":
        return ast.ClassDef(dct["name"], dct["bases"], dct["body"],
                            dct["decorator_list"])
    elif dct['ast_type'] == "Return":
        return ast.Return(dct["value"])
    elif dct['ast_type'] == "Delete":
        return ast.Delete(dct["targets"])
    elif dct['ast_type'] == "Assign":
        return ast.Assign(dct["targets"], dct["value"])
    elif dct['ast_type'] == "AugAssign":
        return ast.AugAssign(dct["target"], dct["op"], dct["value"])
    elif dct['ast_type'] == "Print":
        return ast.Print(dct["dest"], dct["values"], dct["nl"])
    elif dct['ast_type'] == "For":
        return ast.For(dct["target"], dct["iter"], dct["body"], dct["orelse"])
    elif dct['ast_type'] == "While":
        return ast.While(dct["test"], dct["body"], dct["orelse"])
    elif dct['ast_type'] == "If":
        return ast.If(dct["test"], dct["body"], dct["orelse"])
    elif dct['ast_type'] == "With":
        return ast.With(dct["context_expr"], dct["optional_vars"], dct["body"])
    elif dct['ast_type'] == "Raise":
        return ast.Raise(dct["type"], dct["inst"], dct["tback"])
    elif dct['ast_type'] == "TryExcept":
        return ast.TryExcept(dct["body"], dct["handlers"], dct["orelse"])
    elif dct['ast_type'] == "TryFinally":
        return ast.TryFinally(dct["body"], dct["finalbody"])
    elif dct['ast_type'] == "Assert":
        return ast.Assert(dct["test"], dct["msg"])
    elif dct['ast_type'] == "Import":
        return ast.Import(dct["names"])
    elif dct['ast_type'] == "ImportFrom":
        return ast.ImportFrom(dct["module"], dct["names"], dct["level"])
    elif dct['ast_type'] == "Exec":
        return ast.Exec(dct["body"], dct["globals"], dct["locals"])
    elif dct['ast_type'] == "Global":
        return ast.Global(dct["names"])
    elif dct['ast_type'] == "Expr":
        return ast.Expr(dct["value"])
    elif dct['ast_type'] == "Pass":
        return ast.Pass()
    elif dct['ast_type'] == "Break":
        return ast.Break()
    elif dct['ast_type'] == "Continue":
        return ast.Continue()
    elif dct['ast_type'] == "BoolOp":
        return ast.BoolOp(dct["op"], dct["values"])
    elif dct['ast_type'] == "BinOp":
        return ast.BinOp(dct["left"], dct["op"], dct["right"])
    elif dct['ast_type'] == "UnaryOp":
        return ast.UnaryOp(dct["op"], dct["operand"])
    elif dct['ast_type'] == "Lambda":
        return ast.Lambda(dct["args"], dct["body"])
    elif dct['ast_type'] == "IfExp":
        return ast.IfExp(dct["test"], dct["body"], dct["orelse"])
    elif dct['ast_type'] == "Dict":
        return ast.Dict(dct["keys"], dct["values"])
    elif dct['ast_type'] == "Set":
        return ast.Set(dct["elts"])
    elif dct['ast_type'] == "ListComp":
        return ast.ListComp(dct["elt"], dct["generators"])
    elif dct['ast_type'] == "SetComp":
        return ast.SetComp(dct["elt"], dct["generators"])
    elif dct['ast_type'] == "DictComp":
        return ast.DictComp(dct["key"], dct["value"], dct["generators"])
    elif dct['ast_type'] == "GeneratorExp":
        return ast.GeneratorExp(dct["elt"], dct["generators"])
    elif dct['ast_type'] == "Yield":
        return ast.Yield(dct["value"])
    elif dct['ast_type'] == "Compare":
        return ast.Compare(dct["left"], dct["ops"], dct["comparators"])
    elif dct['ast_type'] == "Call":
        return ast.Call(dct["func"], dct["args"], dct["keywords"],
                        dct["starargs"], dct["kwargs"])
    elif dct['ast_type'] == "Repr":
        return ast.Repr(dct["value"])
    elif dct['ast_type'] == "Num":
        return ast.Num(dct["n"])
    elif dct['ast_type'] == "Str":
        # Converting to ASCII
        return ast.Str(dct["s"].encode('ascii', 'ignore'))
    elif dct['ast_type'] == "Attribute":
        return ast.Attribute(dct["value"], dct["attr"], dct["ctx"])
    elif dct['ast_type'] == "Subscript":
        return ast.Subscript(dct["value"], dct["slice"], dct["ctx"])
    elif dct['ast_type'] == "Name":
        return ast.Name(dct["id"], dct["ctx"])
    elif dct['ast_type'] == "List":
        return ast.List(dct["elts"], dct["ctx"])
    elif dct['ast_type'] == "Tuple":
        return ast.Tuple(dct["elts"], dct["ctx"])
    elif dct['ast_type'] == "Load":
        return ast.Load()
    elif dct['ast_type'] == "Store":
        return ast.Store()
    elif dct['ast_type'] == "Del":
        return ast.Del()
    elif dct['ast_type'] == "AugLoad":
        return ast.AugLoad()
    elif dct['ast_type'] == "AugStore":
        return ast.AugStore()
    elif dct['ast_type'] == "Param":
        return ast.Param()
    elif dct['ast_type'] == "Ellipsis":
        return ast.Ellipsis()
    elif dct['ast_type'] == "Slice":
        return ast.Slice(dct["lower"], dct["upper"], dct["step"])
    elif dct['ast_type'] == "ExtSlice":
        return ast.ExtSlice(dct["dims"])
    elif dct['ast_type'] == "Index":
        return ast.Index(dct["value"])
    elif dct['ast_type'] == "And":
        return ast.And()
    elif dct['ast_type'] == "Or":
        return ast.Or()
    elif dct['ast_type'] == "Add":
        return ast.Add()
    elif dct['ast_type'] == "Sub":
        return ast.Sub()
    elif dct['ast_type'] == "Mult":
        return ast.Mult()
    elif dct['ast_type'] == "Div":
        return ast.Div()
    elif dct['ast_type'] == "Mod":
        return ast.Mod()
    elif dct['ast_type'] == "Pow":
        return ast.Pow()
    elif dct['ast_type'] == "LShift":
        return ast.LShift()
    elif dct['ast_type'] == "RShift":
        return ast.RShift()
    elif dct['ast_type'] == "BitOr":
        return ast.BitOr()
    elif dct['ast_type'] == "BitXor":
        return ast.BitXor()
    elif dct['ast_type'] == "BitAnd":
        return ast.BitAnd()
    elif dct['ast_type'] == "FloorDiv":
        return ast.FloorDiv()
    elif dct['ast_type'] == "Invert":
        return ast.Invert()
    elif dct['ast_type'] == "Not":
        return ast.Not()
    elif dct['ast_type'] == "UAdd":
        return ast.UAdd()
    elif dct['ast_type'] == "USub":
        return ast.USub()
    elif dct['ast_type'] == "Eq":
        return ast.Eq()
    elif dct['ast_type'] == "NotEq":
        return ast.NotEq()
    elif dct['ast_type'] == "Lt":
        return ast.Lt()
    elif dct['ast_type'] == "LtE":
        return ast.LtE()
    elif dct['ast_type'] == "Gt":
        return ast.Gt()
    elif dct['ast_type'] == "GtE":
        return ast.GtE()
    elif dct['ast_type'] == "Is":
        return ast.Is()
    elif dct['ast_type'] == "IsNot":
        return ast.IsNot()
    elif dct['ast_type'] == "In":
        return ast.In()
    elif dct['ast_type'] == "NotIn":
        return ast.NotIn()
    elif dct['ast_type'] == "comprehension":
        return ast.comprehension(dct["target"], dct["iter"], dct["ifs"])
    elif dct['ast_type'] == "ExceptHandler":
        return ast.ExceptHandler(dct["type"], dct["name"], dct["body"])
    elif dct['ast_type'] == "arguments":
        return ast.arguments(dct["args"], dct["vararg"], dct["kwarg"],
                             dct["defaults"])
    elif dct['ast_type'] == "keyword":
        return ast.keyword(dct["arg"], dct["value"])
    elif dct['ast_type'] == "alias":
        return ast.alias(dct["name"], dct["asname"])
    else:
        return dct
Exemplo n.º 30
0
def compile_restricted_function(
        p,  # parameters
        body,
        name,
        filename='<string>',
        globalize=None,  # List of globals (e.g. ['here', 'context', ...])
        flags=0,
        dont_inherit=False,
        policy=RestrictingNodeTransformer):
    """Compile a restricted code object for a function.

    The globalize argument, if specified, is a list of variable names to be
    treated as globals (code is generated as if each name in the list
    appeared in a global statement at the top of the function).
    This allows to inject global variables into the generated function that
    feel like they are local variables, so the programmer who uses this doesn't
    have to understand that his code is executed inside a function scope
    instead of the global scope of a module.

    To actually get an executable function, you need to execute this code and
    pull out the defined function out of the locals like this:

    >>> compiled = compile_restricted_function('', 'pass', 'function_name')
    >>> safe_locals = {}
    >>> safe_globals = {}
    >>> exec(compiled.code, safe_globals, safe_locals)
    >>> compiled_function = safe_locals['function_name']
    >>> result = compiled_function(*[], **{})

    Then if you want to controll the globals for a specific call to this
    function, you can regenerate the function like this:

    >>> my_call_specific_global_bindings = dict(foo='bar')
    >>> safe_globals = safe_globals.copy()
    >>> safe_globals.update(my_call_specific_global_bindings)
    >>> import types
    >>> new_function = types.FunctionType(compiled_function.__code__, \
                                          safe_globals, \
                                          '<function_name>', \
                                          compiled_function.__defaults__ or \
                                          () \
                                          )
    >>> result = new_function(*[], **{})
    """
    # Parse the parameters and body, then combine them.
    body_ast = ast.parse(body, '<func code>', 'exec')

    # The compiled code is actually executed inside a function
    # (that is called when the code is called) so reading and assigning to a
    # global variable like this`printed += 'foo'` would throw an
    # UnboundLocalError.
    # We don't want the user to need to understand this.
    if globalize:
        body_ast.body.insert(0, ast.Global(globalize))
    wrapper_ast = ast.parse('def masked_function_name(%s): pass' % p,
                            '<func wrapper>', 'exec')
    # In case the name you chose for your generated function is not a
    # valid python identifier we set it after the fact
    function_ast = wrapper_ast.body[0]
    assert isinstance(function_ast, ast.FunctionDef)
    function_ast.name = name

    wrapper_ast.body[0].body = body_ast.body
    wrapper_ast = ast.fix_missing_locations(wrapper_ast)

    result = _compile_restricted_mode(wrapper_ast,
                                      filename=filename,
                                      mode='exec',
                                      flags=flags,
                                      dont_inherit=dont_inherit,
                                      policy=policy)

    return result