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))
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
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)], [])
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
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
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
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]
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
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
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, )
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
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
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), ]) ])
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)) ]
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
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
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)
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
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)
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))
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)))
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()
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]
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