Exemplo n.º 1
0
    def visitWith(self, node):

        i = self.withcnt()
        abc, exc = 'WiTh_CoNtExT__%i' % i, 'WiTh_ExC__%i' % i
        lno = node.lineno
        self.visit(node.expr)
        self.visit(node.code)
        rbc = hasRBC(node.code)
        stmts = []
        stmts.append(
            ast_Assign(abc,
                       ast.CallFunc(ast.Getattr(node.expr, '__context__'),
                                    [])))
        if rbc:
            stmts.append(ast_Assign(exc, ast.Const((None, None, None))))
        enter = ast.CallFunc(ast_Getattr(abc, '__enter__'), [])
        if node.var:
            enter = ast_Assign(node.var, enter)
        else:
            enter = ast.Discard(enter)
        stmts.append(enter)
        if rbc:
            stmts.append(
                ast.TryFinally(
                    ast.TryExcept(
                        node.code,
                        [(None, None,
                          ast.Stmt([
                              ast_Assign(
                                  exc,
                                  ast.CallFunc(ast_Getattr('sys', 'exc_info'),
                                               [])),
                              ast.Raise(None, None, None, lno)
                          ]))], None, lno),
                    ast.Discard(
                        ast.CallFunc(ast_Getattr(abc, '__exit__'), [],
                                     ast.Name(exc, 0))), lno))
        else:
            stmts.append(
                ast.TryExcept(
                    node.code,
                    [(None, None,
                      ast.Stmt([
                          ast.Discard(
                              ast.CallFunc(
                                  ast_Getattr(abc, '__exit__'), [],
                                  ast.CallFunc(ast_Getattr('sys', 'exc_info'),
                                               []))),
                          ast.Raise(None, None, None, lno)
                      ]))],
                    ast.Stmt([
                        ast.Discard(
                            ast.CallFunc(ast_Getattr(abc, '__exit__'),
                                         3 * [ast.Const(None)]))
                    ]), lno))
        make_copy(node, ast.Stmt(stmts))
Exemplo n.º 2
0
        def generic_visit(self, node):
            import ast
            import sys
            ast.NodeTransformer.generic_visit(self, node)

            if isinstance(node,
                          ast.stmt) and not isinstance(node, ast.FunctionDef):
                if sys.version_info[0] == 3:
                    new_node = ast.Try(body=[node],
                                       handlers=[
                                           ast.ExceptHandler(type=None,
                                                             name=None,
                                                             body=[ast.Pass()])
                                       ],
                                       orelse=[],
                                       finalbody=[ast.Pass()])
                else:
                    new_node = ast.TryExcept(body=[node],
                                             handlers=[
                                                 ast.ExceptHandler(
                                                     type=None,
                                                     name=None,
                                                     body=[ast.Pass()])
                                             ],
                                             orelse=[])
                return ast.copy_location(new_node, node)
            return node
Exemplo n.º 3
0
 def visit_TryFinally(self, node):
     node.body.extend(node.finalbody)
     node.finalbody.append(ast.Raise(None, None, None))
     self.update = True
     return ast.TryExcept(node.body,
                          [ast.ExceptHandler(None, None, node.finalbody)],
                          [])
Exemplo n.º 4
0
    def python_ast(self):

        te = ast.TryExcept(lineno=self.line, col_offset=self.column)
        te.handlers = []
        te.body = self.try_sequence.python_ast()
        for k, v in self.catches.items():
            if k == "#default#":
                eh = ast.ExceptHandler(lineno=self.line,
                                       col_offset=self.column)
                eh.type = None
                eh.name = None
                eh.body = v.python_ast()
                te.handlers.append(eh)
            else:
                eh = ast.ExceptHandler(lineno=self.line,
                                       col_offset=self.column)
                eh.type = ast.Name(k,
                                   ast.Load(),
                                   lineno=self.line,
                                   col_offset=self.column)
                eh.name = None
                eh.body = v.python_ast()
                te.handlers.append(eh)
        te.orelse = []
        return te
Exemplo n.º 5
0
 def get_import_code(self, node, fname='<string>'):
     """Get compiled code of all top-level import statements found in the
     AST of node."""
     self._import_nodes = []
     self.visit(node)
     body = []
     for imp_node in self._import_nodes:
         if isinstance(imp_node, ast.ImportFrom) and \
            imp_node.module == '__future__':
             # 'SyntaxError: from __future__ imports must occur at the
             # beginning of the file' is raised if a 'from __future__ import'
             # is wrapped in try-except, so use only the import statement.
             body.append(imp_node)
         else:
             body.append(
                 ast.TryExcept(body=[imp_node],
                               handlers=[
                                   ast.ExceptHandler(type=None,
                                                     name=None,
                                                     body=[ast.Pass()])
                               ],
                               orelse=[]))
     node = ast.Module(body=body)
     ast.fix_missing_locations(node)
     code = compile(node, fname, 'exec')
     return code
Exemplo n.º 6
0
    def generic_visit(self, node):
        """Surround node statement with a try/except block to catch errors.

        This method is called for every node of the parsed code, and only
        changes statement lines.

        Args:
            node (ast.AST): node statement to surround.
        """
        super(ErrorsCatchTransformer, self).generic_visit(node)

        if (isinstance(node, ast.stmt)
                and not isinstance(node, ast.FunctionDef)):

            if sys.version_info > (3, 0):
                new_node = ast.Try(  # pylint: disable=no-member
                    orelse=[],
                    body=[node],
                    finalbody=[],
                    handlers=self.exception_handlers)

            else:
                new_node = ast.TryExcept(  # pylint: disable=no-member
                    orelse=[],
                    body=[node],
                    handlers=self.exception_handlers)

            return ast.copy_location(new_node, node)

        return node
Exemplo n.º 7
0
 def create_try_except_block(self, node):
     # Creates the entire try except block
     try_body = self.create_try_block(node)
     except_body = self.create_except_block(node)
     try_except_statement = ast.TryExcept(body=try_body,
                                          handlers=except_body,
                                          orelse=[])
     return [try_except_statement]
Exemplo n.º 8
0
 def visit_TryExcept(self, node):
     if node.orelse:
         node.body.append(
             ast.TryExcept(node.orelse,
                           [ast.ExceptHandler(None, None, [ast.Pass()])],
                           []))
         node.orelse = []
     return node
Exemplo n.º 9
0
        def replace_unsafe_value(node, replace_self=None):
            """Modify value from assignment if unsafe.

            If replace_self is given, only assignments starting with 'self.' are
            processed, the assignment node is returned with 'self.' replaced by
            the value of replace_self (typically the class name).
            For other assignments, None is returned."""
            for i, target in enumerate(node.targets):
                if not isinstance(target, (ast.Name, ast.Attribute)):
                    # Only process assignments to names and attributes,
                    # not tuples.
                    return None
                if replace_self:
                    if isinstance(target, ast.Attribute) and \
                       isinstance(target.value, ast.Name) and \
                       target.value.id == 'self' and \
                       isinstance(target.value.ctx, ast.Load):
                        node.targets[i].value.id = replace_self
                        if target.attr == '__name__':
                            node.value = ast.copy_location(ast.Str(s=''),
                                                           node.value)
                        elif target.attr in ('__dict__', '__class__', '__bases__',
                                             '__doc__'):
                            return None
                    else:
                        return None
                elif isinstance(target, ast.Name) and \
                   isinstance(target.ctx, ast.Store):
                   if target.id == '__metaclass__':
                       # Do not modify __metaclass__ assignments
                       return node
                   elif target.id == '__slots__':
                       node.value = ast.copy_location(
                           ast.List(elts=[], ctx=ast.Load()), node.value)
            if isinstance(node.value, (ast.Str, ast.Num)):
                pass
            elif isinstance(node.value, (ast.List, ast.Tuple)):
                node.value.elts = []
            elif isinstance(node.value, ast.Dict):
                node.value.keys = []
                node.value.values = []
            elif isinstance(node.value, ast.ListComp):
                node.value = ast.copy_location(ast.List(elts=[], ctx=ast.Load()), node.value)
            elif isinstance(node.value, ast.Call):
                type_node = _PyCompleteDocument.CodeRemover._get_type_node_for_function_node(node.value.func)
                if type_node:
                    # Wrap class lookup in try-except because it is not fail-safe.
                    node.value = ast.copy_location(type_node, node.value)
                    node = ast.copy_location(ast.TryExcept(body=[node], handlers=[
                        ast.ExceptHandler(type=None, name=None, body=[ast.Pass()])],
                        orelse=[]), node)
                    ast.fix_missing_locations(node)
                else:
                    node.value = ast.copy_location(
                        ast.Name(id='None', ctx=ast.Load()), node.value)
            else:
                node.value = ast.copy_location(ast.Name(id='None', ctx=ast.Load()), node.value)
            return node
Exemplo n.º 10
0
def stmt_try_except(top, handlers):
    return ast.TryExcept(
        body=top,
        handlers=[
            ast.ExceptHandler(type=name(k), name=None, body=v, lineno=1, col_offset=0)
            for k, v in handlers.items()
        ],
        orelse=[],
        lineno=1,
        col_offset=0,
    )
Exemplo n.º 11
0
 def visit_Try(self, node):
     if node.finalbody:
         new_node = ast.TryFinally(self._visit(node.body),
                                   self._visit(node.finalbody))
     else:
         new_node = ast.TryExcept(
             self._visit(node.body),
             self._visit(node.handlers),
             self._visit(node.orelse),
         )
     ast.copy_location(new_node, node)
     return new_node
Exemplo n.º 12
0
        def generic_visit(self, node):
            import ast
            ast.NodeTransformer.generic_visit(self, node)

            if isinstance(node,
                          ast.stmt) and not isinstance(node, ast.FunctionDef):
                return ast.copy_location(
                    ast.TryExcept(body=[node],
                                  handlers=[
                                      ast.ExceptHandler(type=None,
                                                        name=None,
                                                        body=[ast.Pass()])
                                  ],
                                  orelse=[]), node)
            return node
Exemplo n.º 13
0
def convert_assign_py2(lhs, rhs):
    loaded = convert_name(lhs, ast.Load())
    return ast.TryExcept(body=[
        ast.Expr(loaded),
    ],
                         handlers=[gen_except_handler(ast.Assign([lhs], rhs))],
                         orelse=[
                             ast.If(test=gen_hasattr_call(
                                 loaded, BOX_SIGNATURE),
                                    body=[
                                        ast.Expr(gen_box_call(loaded, rhs)),
                                    ],
                                    orelse=[
                                        ast.Assign([lhs], rhs),
                                    ])
                         ])
Exemplo n.º 14
0
    def __call__(self, target, engine):
        ignore = store("_ignore")
        body = engine(self.expression, ignore)

        classes = map(resolve_global, self.exceptions)

        return [
            ast.TryExcept(body=body,
                          handlers=[
                              ast.ExceptHandler(
                                  type=ast.Tuple(elts=classes, ctx=ast.Load()),
                                  name=None,
                                  body=template("target = 0", target=target),
                              )
                          ],
                          orelse=template("target = 1", target=target))
        ]
Exemplo n.º 15
0
    def __call__(self, target, engine):
        remaining = self.expression
        assignments = []

        while remaining:
            if match_prefix(remaining) is not None:
                assignment = engine(remaining, target)
                remaining = ""
            else:
                for m in split_parts.finditer(remaining):
                    expression = remaining[:m.start()]
                    remaining = remaining[m.end():]
                    break
                else:
                    expression = remaining
                    remaining = ""

                expression = expression.replace('\\|', '|')
                assignment = self.translate(expression, target)
            assignments.append(assignment)

        if not assignments:
            assignments.append(self.translate(remaining, target))

        for i, assignment in enumerate(reversed(assignments)):
            if i == 0:
                body = assignment
            else:
                body = [
                    ast.TryExcept(
                        body=assignment,
                        handlers=[
                            ast.ExceptHandler(
                                type=ast.Tuple(elts=map(
                                    resolve_global, self.exceptions),
                                               ctx=ast.Load()),
                                name=None,
                                body=body,
                            )
                        ],
                    )
                ]

        return body
Exemplo n.º 16
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.º 17
0
 def visitTryExcept(self, n, *args):
     body = self.dispatch_statements(n.body, *args)
     handlers = self.reduce(n.handlers, *args)
     orelse = self.dispatch_statements(n.orelse, *args)
     return ast.TryExcept(body=body, handlers=handlers, orelse=orelse)
Exemplo n.º 18
0
    def visit_With(self, node):
        node = self.generic_visit(node)

        # Build equivalent code with try catch finally.
        # PEP-0343 provides the equivalent code for us.

        statements = []

        # mgr = node.expr
        mgr_id = self.id_factory("mgr")
        s = mk_assign(mgr_id, node.context_expr)
        statements.append(s)

        # exit = type(msg).__exit__
        exit_id = self.id_factory("exit")
        s = mk_assign(exit_id,
                      mk_attr(mk_call('type', [mk_name(mgr_id)]), "__exit__"))
        statements.append(s)

        # value = type(msg).__enter__(mgr)
        value_id = self.id_factory("value")
        s = mk_assign(
            value_id,
            mk_call_expr(
                mk_attr(mk_call('type', [mk_name(mgr_id)]), "__enter__"),
                [mk_name(mgr_id)]))
        statements.append(s)

        # exc = True
        exc_id = self.id_factory("exc")
        s = mk_assign(exc_id, mk_name("True"))
        statements.append(s)

        # try:
        tryfinally_body = []
        tryfinally_finalbody = []
        s = ast.TryFinally(body=tryfinally_body,
                           finalbody=tryfinally_finalbody)
        statements.append(s)

        #     try:
        tryexcept_body = []
        tryexcept_except = []
        expt_handler = ast.ExceptHandler(type=None,
                                         name=None,
                                         body=tryexcept_except)
        s = ast.TryExcept(body=tryexcept_body,
                          handlers=[expt_handler],
                          orelse=[])
        tryfinally_body.append(s)

        #         node.optional_vars = value
        if node.optional_vars:
            s = ast.Assign(targets=[node.optional_vars],
                           value=mk_name(value_id))
            tryexcept_body.append(s)

        #         body
        tryexcept_body.extend(node.body)

        #     except:

        #         exc = False
        s = mk_assign(exc_id, mk_name("False"))
        tryexcept_except.append(s)

        #         sys.exc_info()
        sys_exc_info = mk_call_expr(mk_attr(mk_name('sys'), "exc_info"), [])
        #         exit(mgr, *sys.exc_info())
        exit_call = mk_call(exit_id, [mk_name(mgr_id)], vararg=sys_exc_info)
        #         not exit(mgr, *sys.exc_info())
        test = ast.UnaryOp(op=ast.Not(), operand=exit_call)

        #        if not exit(mgr, *sys.exc_info()):
        #            raise
        s = ast.If(test=test,
                   body=[ast.Raise(type=None, inst=None, tback=None)],
                   orelse=[])
        tryexcept_except.append(s)

        # finally:

        #     if exc:
        #       exit(mgr, None, None, None)
        exit_call = mk_call(exit_id, [
            mk_name(mgr_id),
            mk_name("None"),
            mk_name("None"),
            mk_name("None")
        ])
        s = ast.If(test=mk_name(exc_id),
                   body=[ast.Expr(value=exit_call)],
                   orelse=[])
        tryfinally_finalbody.append(s)

        return statements
Exemplo n.º 19
0
    def compile_try_expression(self, expr):
        expr.pop(0)  # try

        try:
            body = expr.pop(0)
        except IndexError:
            body = []

        # (try something…)
        body = self._code_branch(self.compile(body), expr.start_line,
                                 expr.start_column)

        orelse = []
        finalbody = []
        handlers = []

        for e in expr:
            if not len(e):
                raise HyTypeError(e, "Empty list not allowed in `try'")

            if e[0] in (HySymbol("except"), HySymbol("catch")):
                handlers.append(self.compile(e))
            elif e[0] == HySymbol("else"):
                if orelse:
                    raise HyTypeError(
                        e, "`try' cannot have more than one `else'")
                else:
                    orelse = self._code_branch(self.compile(e[1:]),
                                               e.start_line, e.start_column)
            elif e[0] == HySymbol("finally"):
                if finalbody:
                    raise HyTypeError(
                        e, "`try' cannot have more than one `finally'")
                else:
                    finalbody = self._code_branch(self.compile(e[1:]),
                                                  e.start_line, e.start_column)
            else:
                raise HyTypeError(e, "Unknown expression in `try'")

        # Using (else) without (except) is verboten!
        if orelse and not handlers:
            raise HyTypeError(e, "`try' cannot have `else' without `except'")

        # (try) or (try BODY)
        # Generate a default handler for Python >= 3.3 and pypy
        if not handlers and not finalbody and not orelse:
            handlers = [
                ast.ExceptHandler(lineno=expr.start_line,
                                  col_offset=expr.start_column,
                                  type=None,
                                  name=None,
                                  body=[
                                      ast.Pass(lineno=expr.start_line,
                                               col_offset=expr.start_column)
                                  ])
            ]

        if sys.version_info[0] >= 3 and sys.version_info[1] >= 3:
            # Python 3.3 features a merge of TryExcept+TryFinally into Try.
            return ast.Try(lineno=expr.start_line,
                           col_offset=expr.start_column,
                           body=body,
                           handlers=handlers,
                           orelse=orelse,
                           finalbody=finalbody)

        if finalbody:
            if handlers:
                return ast.TryFinally(lineno=expr.start_line,
                                      col_offset=expr.start_column,
                                      body=[
                                          ast.TryExcept(
                                              lineno=expr.start_line,
                                              col_offset=expr.start_column,
                                              handlers=handlers,
                                              body=body,
                                              orelse=orelse)
                                      ],
                                      finalbody=finalbody)

            return ast.TryFinally(lineno=expr.start_line,
                                  col_offset=expr.start_column,
                                  body=body,
                                  finalbody=finalbody)

        return ast.TryExcept(lineno=expr.start_line,
                             col_offset=expr.start_column,
                             handlers=handlers,
                             body=body,
                             orelse=orelse)
Exemplo n.º 20
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.º 21
0
    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 self.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(map(to_stmt, map(self.from_phpast, node.nodes)),
                            [py.ExceptHandler(py.Name(catch.class_,
                                                      py.Load(**pos(node)),
                                                      **pos(node)),
                                                  store(self.from_phpast(catch.var)),
                                                  map(to_stmt, map(self.from_phpast, catch.nodes)),
                                              **pos(node))
                             for catch in node.catches],
                            [],
                            **pos(node))

    if isinstance(node, php.Throw):
            return py.Raise(self.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)))
Exemplo n.º 22
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.º 23
0
    def instantiateFunction(self, filename, lineNumber, memberDictionary,
                            file_text):
        """Instantiate a function instance."""

        memberDictionary = {
            k: v
            for k, v in memberDictionary.iteritems()
            if not isinstance(v, Exceptions.PyforaNameError)
        }

        objectOrNone = self.moduleLevelObject(filename, lineNumber)
        if objectOrNone is not None:
            return objectOrNone

        sourceAst = PyAstUtil.pyAstFromText(file_text)
        functionAst = PyAstUtil.functionDefOrLambdaOrWithBlockAtLineNumber(
            sourceAst, lineNumber)

        outputLocals = {}
        globalScope = {}
        globalScope.update(memberDictionary)
        self.importModuleMagicVariables(globalScope, filename)

        if isinstance(functionAst, ast.Lambda):
            expr = ast.FunctionDef()
            expr.name = '__pyfora_lambda_builder__'
            expr.args = ast.arguments()
            expr.args.args = []
            expr.args.defaults = []
            expr.args.vararg = None
            expr.args.kwarg = None

            expr.decorator_list = []
            expr.lineno = functionAst.lineno - 1
            expr.col_offset = functionAst.col_offset

            return_statement = ast.Return(functionAst)
            expr.body = [return_statement]

            expr = updatePyAstMemberChains(ast.Module([expr],
                                                      lineno=1,
                                                      col_offset=0),
                                           globalScope,
                                           isClassContext=True)

            code = compile(expr, filename, 'exec')

            exec code in globalScope, outputLocals

            return list(outputLocals.values())[0]()

        elif isinstance(functionAst, ast.With):
            expr = ast.FunctionDef()
            expr.name = '__pyfora_with_block_as_function__'
            expr.args = ast.arguments()
            expr.args.args = []
            expr.args.defaults = []
            expr.args.vararg = None
            expr.args.kwarg = None

            expr.decorator_list = []

            #make sure we copy the list - if we use the existing one, we will mess up the
            #cached copy!
            expr.body = list(functionAst.body)
            expr.lineno = functionAst.lineno - 1
            expr.col_offset = functionAst.col_offset

            bound_variables = PyAstFreeVariableAnalyses.collectBoundValuesInScope(
                expr)

            return_dict_list_src = "[" + ",".join(
                "'%s'" % k for k in bound_variables) + "]"
            return_dict_expr_src = "{{k: __locals[k] for k in {return_dict_list_src} if k in __locals}}".format(
                return_dict_list_src=return_dict_list_src)
            return_dict_expr_src = "(lambda __locals: {return_dict_expr_src})(dict(locals()))".format(
                return_dict_expr_src=return_dict_expr_src)

            return_dict_expr = ast.parse(return_dict_expr_src).body[0].value

            return_statement = ast.Return(
                ast.Tuple(
                    [return_dict_expr,
                     ast.Num(0), ast.Num(0)], ast.Load()))

            return_statement_exception = ast.Return(
                ast.Tuple([
                    return_dict_expr,
                    ast.Call(
                        ast.Name("__pyfora_get_exception_traceback__",
                                 ast.Load()), [], [], None, None),
                    ast.Name("__pyfora_exception_var__", ast.Load())
                ], ast.Load()))

            expr.body.append(return_statement)

            handler = ast.ExceptHandler(
                None, ast.Name("__pyfora_exception_var__", ast.Store()),
                [return_statement_exception])

            #now wrap in a try-catch block
            curBody = list(expr.body)
            expr.body = [ast.TryExcept(curBody, [handler], [])]

            #for every incoming variable 'x' that's also assigned to, create a dummy '__pyfora_var_guard_x' that actually
            #takes the value in from the surrounding scope, and immediately assign it
            for var in memberDictionary:
                if var in bound_variables:
                    newVar = "__pyfora_var_guard_" + var

                    var_copy_expr = ast.Assign(
                        targets=[ast.Name(var, ast.Store())],
                        value=ast.Name(newVar, ast.Load()))

                    globalScope[newVar] = globalScope[var]
                    del globalScope[var]

                    expr.body = [var_copy_expr] + expr.body

            expr = updatePyAstMemberChains(expr,
                                           globalScope,
                                           isClassContext=True)

            ast.fix_missing_locations(expr)

            def extractTrace():
                return sys.exc_info()[2]

            globalScope['__pyfora_get_exception_traceback__'] = extractTrace

            code = compile(ast.Module([expr]), filename, 'exec')

            exec code in globalScope, outputLocals
            assert len(outputLocals) == 1
            return list(outputLocals.values())[0]
        else:
            functionAst = updatePyAstMemberChains(ast.Module([functionAst],
                                                             lineno=1,
                                                             col_offset=0),
                                                  globalScope,
                                                  isClassContext=False)

            code = compile(functionAst, filename, 'exec')

            exec code in globalScope, outputLocals
            assert len(outputLocals) == 1
            return list(outputLocals.values())[0]
Exemplo n.º 24
0
    def replace_unsafe_value(node, replace_self=None):
        """Modify value from assignment if unsafe.

        If replace_self is given, only assignments starting with 'self.' are
        processed, the assignment node is returned with 'self.' replaced by
        the value of replace_self (typically the class name).
        For other assignments, None is returned."""
        if replace_self:
            if len(node.targets) != 1:
                return None
            target = node.targets[0]
            if isinstance(target, ast.Attribute) and \
               isinstance(target.value, ast.Name) and \
               target.value.id == 'self' and \
               isinstance(target.value.ctx, ast.Load):
                node.targets[0].value.id = replace_self
            else:
                return None
        if isinstance(node.value, (ast.Str, ast.Num)):
            pass
        elif isinstance(node.value, (ast.List, ast.Tuple)):
            node.value.elts = []
        elif isinstance(node.value, ast.Dict):
            node.value.keys = []
            node.value.values = []
        elif isinstance(node.value, ast.ListComp):
            node.value = ast.copy_location(ast.List(elts=[], ctx=ast.Load()),
                                           node.value)
        elif isinstance(node.value, ast.Call):
            if isinstance(node.value.func, ast.Name):
                name = node.value.func.id
                if name == 'open':
                    if sys.version_info[0] >= 3:  # Python 3
                        node.value = ast.copy_location(
                            ast.Attribute(value=ast.Name(id='io',
                                                         ctx=ast.Load()),
                                          attr='BufferedIOBase',
                                          ctx=ast.Load()), node.value)
                    else:  # Python 2
                        node.value = ast.copy_location(
                            ast.Name(id='file', ctx=ast.Load()), node.value)
                    # Wrap class lookup in try-except because it is not fail-safe.
                    node = ast.copy_location(
                        ast.TryExcept(body=[node],
                                      handlers=[
                                          ast.ExceptHandler(type=None,
                                                            name=None,
                                                            body=[ast.Pass()])
                                      ],
                                      orelse=[]), node)
                    ast.fix_missing_locations(node)
                elif CodeRemover._classNameRe.match(name):
                    node.value = ast.copy_location(
                        ast.Name(id=name, ctx=ast.Load()), node.value)
                    # Wrap class lookup in try-except because it is not fail-safe.
                    node = ast.copy_location(
                        ast.TryExcept(body=[node],
                                      handlers=[
                                          ast.ExceptHandler(type=None,
                                                            name=None,
                                                            body=[ast.Pass()])
                                      ],
                                      orelse=[]), node)
                    ast.fix_missing_locations(node)
                else:
                    node.value = ast.copy_location(
                        ast.Name(id='None', ctx=ast.Load()), node.value)
            elif isinstance(node.value.func, ast.Attribute) and \
                 CodeRemover._classNameRe.match(node.value.func.attr):
                node.value = node.value.func
                # Wrap class lookup in try-except because it is not fail-safe.
                node = ast.copy_location(
                    ast.TryExcept(body=[node],
                                  handlers=[
                                      ast.ExceptHandler(type=None,
                                                        name=None,
                                                        body=[ast.Pass()])
                                  ],
                                  orelse=[]), node)
                ast.fix_missing_locations(node)
            else:
                node.value = ast.copy_location(
                    ast.Name(id='None', ctx=ast.Load()), node.value)
        else:
            node.value = ast.copy_location(ast.Name(id='None', ctx=ast.Load()),
                                           node.value)
        return node