def test_raise(self): r = ast.Raise(None, ast.Num(3)) self.stmt(r, "Raise with cause but no exception") r = ast.Raise(ast.Name("x", ast.Store()), None) self.stmt(r, "must have Load context") r = ast.Raise(ast.Num(4), ast.Name("x", ast.Store())) self.stmt(r, "must have Load context")
def visit_Assert(self, assert_): """Return the AST statements to replace the ast.Assert instance. This rewrites the test of an assertion to provide intermediate values and replace it with an if statement which raises an assertion error with a detailed explanation in case the expression is false. """ if isinstance(assert_.test, ast.Tuple) and len(assert_.test.elts) >= 1: from _pytest.warning_types import PytestWarning import warnings warnings.warn_explicit( PytestWarning( "assertion is always true, perhaps remove parentheses?"), category=None, filename=str(self.module_path), lineno=assert_.lineno, ) self.statements = [] self.variables = [] self.variable_counter = itertools.count() self.stack = [] self.on_failure = [] self.push_format_context() # Rewrite assert into a bunch of statements. top_condition, explanation = self.visit(assert_.test) # Create failure message. body = self.on_failure negation = ast.UnaryOp(ast.Not(), top_condition) self.statements.append(ast.If(negation, body, [])) if assert_.msg: assertmsg = self.helper("format_assertmsg", assert_.msg) explanation = "\n>assert " + explanation else: assertmsg = ast.Str("") explanation = "assert " + explanation template = ast.BinOp(assertmsg, ast.Add(), ast.Str(explanation)) msg = self.pop_format_context(template) fmt = self.helper("format_explanation", msg) err_name = ast.Name("AssertionError", ast.Load()) exc = ast_Call(err_name, [fmt], []) if sys.version_info[0] >= 3: raise_ = ast.Raise(exc, None) else: raise_ = ast.Raise(exc, None, None) body.append(raise_) # Clear temporary variables by setting them to None. if self.variables: variables = [ ast.Name(name, ast.Store()) for name in self.variables ] clear = ast.Assign(variables, _NameConstant(None)) self.statements.append(clear) # Fix line numbers. for stmt in self.statements: set_location(stmt, assert_.lineno, assert_.col_offset) return self.statements
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 visitRaise(self, n, *args): if flags.PY_VERSION == 3: exc = self.dispatch(n.exc, *args) if n.exc else None cause = self.dispatch(n.cause, *args) if n.cause else None return ast.Raise(exc=exc, cause=cause) elif flags.PY_VERSION == 2: type = self.dispatch(n.type, *args) if n.type else None inst = self.dispatch(n.inst, *args) if n.inst else None tback = self.dispatch(n.tback, *args) if n.tback else None return ast.Raise(type=type, inst=inst, tback=tback)
def visit_Assert(self, node): node = self.generic_visit(node) if node.msg: inst = mk_call("AssertionError", [node.msg]) raise_stmt = ast.Raise(type=inst, inst=None, tback=None) else: raise_stmt = ast.Raise(type=mk_name("AssertionError"), inst=None, tback=None) check = ast.If(test=mk_not(node.test), body=[raise_stmt], orelse=[]) return ast.If(test=mk_name("__debug__"), body=[check], orelse=[])
def generate(self, element:Element, GC:GenerationContext): acode = element.code #assert isinstance(acode, Form) if len(acode) > 1: with GC.let(domain=ExDom): exception_obj_code = GC.generate(acode[1]) return ast.Raise(exception_obj_code, None) # Fix none to allow raise x from y syntax else: assert len(acode) == 1 return ast.Raise()
def visit_Assert(self, assert_): """Return the AST statements to replace the ast.Assert instance. This re-writes the test of an assertion to provide intermediate values and replace it with an if statement which raises an assertion error with a detailed explanation in case the expression is false. """ self.statements = [] self.variables = [] self.variable_counter = itertools.count() self.stack = [] self.on_failure = [] self.push_format_context() # Rewrite assert into a bunch of statements. top_condition, explanation = self.visit(assert_.test) # Create failure message. body = self.on_failure negation = ast.UnaryOp(ast.Not(), top_condition) self.statements.append(ast.If(negation, body, [])) if assert_.msg: assertmsg = self.helper('format_assertmsg', assert_.msg) explanation = "\n>assert " + explanation else: assertmsg = ast.Str("") explanation = "assert " + explanation template = ast.BinOp(assertmsg, ast.Add(), ast.Str(explanation)) msg = self.pop_format_context(template) fmt = self.helper("format_explanation", msg) err_name = ast.Name("AssertionError", ast.Load()) exc = ast.Call(err_name, [fmt], [], None, None) if sys.version_info[0] >= 3: raise_ = ast.Raise(exc, None) else: raise_ = ast.Raise(exc, None, None) body.append(raise_) # Clear temporary variables by setting them to None. if self.variables: variables = [ ast.Name(name, ast.Store()) for name in self.variables ] clear = ast.Assign(variables, ast.Name("None", ast.Load())) self.statements.append(clear) # Fix line numbers. for stmt in self.statements: set_location(stmt, assert_.lineno, assert_.col_offset) return self.statements
def raise_exception(self, node, exc=None, msg='', expr=None, fname=None, lineno=None, func=None): "add an exception" if self.error is None: self.error = [] if expr is None: expr = self.expr if fname is None: fname = self.fname if lineno is None: lineno = self.lineno if func is None: func = self.func if len(self.error) > 0 and not isinstance(node, ast.Module): msg = '%s' % msg err = LarchExceptionHolder(node=node, exc=exc, msg=msg, expr=expr, fname=fname, lineno=lineno, func=func) self._interrupt = ast.Raise() self.error.append(err) self.symtable._sys.last_error = err
def visit_Assign(self, node: ast.Assign) -> Any: self.generic_visit(node) target = node.targets[0] if not isinstance(target, ast.Name): return node expr = ast.Name(id=target.id, ctx=ast.Load()) name = target.id check = ast.Try( body=[ast.Expr(expr)], handlers=[ ast.ExceptHandler( type=ast.Tuple( elts=[ast.Name(id=_n(NameError), ctx=ast.Load())], ctx=ast.Load(), ), name=None, body=[ast.Expr(value=ast.Constant(value=Ellipsis))], ) ], orelse=[ ast.Raise( exc=ast.Call( func=ast.Name( id=_n(ImmutabilityGuard.proxy_Assign), ctx=ast.Load() ), args=[ast.Constant(value=name)], keywords=[], ), cause=None, ) ], finalbody=[], ) return [check, node]
def __init__(self, ignore_exceptions=(), catch_exception=None): raise_cmd = ast.Raise() if sys.version_info > (3, 0): start_debug_cmd = ast.Expr(value=ast.Call( ast.Name("start_debugging", ast.Load()), [], [], )) else: start_debug_cmd = ast.Expr(value=ast.Call( ast.Name("start_debugging", ast.Load()), [], [], None, None)) catch_exception_node = None if catch_exception is not None: catch_exception_node = ast.Name(catch_exception.__name__, ast.Load()) self.exception_handlers = [ ast.ExceptHandler(type=catch_exception_node, name=None, body=[start_debug_cmd]) ] for exception_class in ignore_exceptions: ignore_exception_node = ast.Name(exception_class.__name__, ast.Load()) self.exception_handlers.insert( 0, ast.ExceptHandler(type=ignore_exception_node, name=None, body=[raise_cmd]))
def p_raise_stmt4(self, p): ''' raise_stmt : RAISE test COMMA test COMMA test ''' raise_stmt = ast.Raise() raise_stmt.type = p[2] raise_stmt.inst = p[4] raise_stmt.tback = p[6] p[0] = raise_stmt
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 visit_FunctionDef(self, node): if len(preconditions[node.name]) == 0: return node ast_name = ast.Name(id="PreconditionException", ctx=ast.Load()) node_exception = ast.Raise(exc=ast_name, cause=None) precondition_node = preconditions[node.name][0] assert_node = ast.Assert(precondition_node, lineno=node.lineno, col_offset=node.col_offset, end_lineno=node.lineno, end_col_offset=node.end_col_offset) ast_exception = ast.Name(id="Exception", ctx=ast.Load()) handler = ast.ExceptHandler(type=ast_exception, name=None, body=[node_exception]) try_node = ast.Try(body=[assert_node], handlers=[handler], orelse=[], finalbody=[node.body]) #if_node = ast.If(precondition_node,[node.body],[node_exception]) node_res = ast.FunctionDef(node.name, node.args, [try_node], node.decorator_list, node.returns, node.type_comment, lineno=node.lineno, col_offset=node.col_offset, end_lineno=node.lineno, end_col_offset=node.end_col_offset) ast.fix_missing_locations(node_res) return node_res
def visit_Raise(self, node: Raise, *args, **kwargs) -> C.Raise: exc = self.visit(node.exc, *args, **kwargs) cause = self.visit(node.cause, *args, **kwargs) return C.Raise( exc=exc, cause=cause, )
def visit_Assert(self, t): t = self.generic_visit(t) result = ast.If(t.test, [], [ ast.Raise( Call(ast.Name('AssertionError', load), [] if t.msg is None else [t.msg]), None) ]) return ast.copy_location(result, t)
def make_raise(): """Raise(expr? exc, expr? cause)""" return ast.Raise( exc=ast.Name(id="exception", ctx=ast.Load()), # Causes aren't that common so let's not include them # in the default raise cause=None # ast.Name(id="cause", ctx=ast.Load()) )
def compile_throw_expression(self, expr): expr.pop(0) exc = self.compile(expr.pop(0)) if expr else None return ast.Raise(lineno=expr.start_line, col_offset=expr.start_column, type=exc, exc=exc, inst=None, tback=None)
def wrap_with_try(self, node): """Wrap an ast node in a 'try' node to enter debug on exception.""" handlers = [] if self.ignore_exceptions is None: handlers.append(ast.ExceptHandler(type=None, name=None, body=[ast.Raise()])) else: ignores_nodes = self.ignore_exceptions handlers.append(ast.ExceptHandler(type=ast.Tuple(ignores_nodes, ast.Load()), name=None, body=[ast.Raise()])) if self.catch_exception is None or \ get_node_value(self.catch_exception) not in \ (get_node_value(ast_node) for ast_node in self.ignore_exceptions): call_extra_parameters = [] if IS_PYTHON_3 else [None, None] start_debug_cmd = ast.Expr( value=ast.Call(ast.Name("start_debugging", ast.Load()), [], [], *call_extra_parameters)) catch_exception_type = None if self.catch_exception is not None: catch_exception_type = self.catch_exception handlers.append(ast.ExceptHandler(type=catch_exception_type, name=None, body=[start_debug_cmd])) try_except_extra_params = {"finalbody": []} if IS_PYTHON_3 else {} new_node = self.ast_try_except(orelse=[], body=[node], handlers=handlers, **try_except_extra_params) return ast.copy_location(new_node, node)
def visit_Assert(self, assert_): if assert_.msg: # There's already a message. Don't mess with it. return [assert_] self.statements = [] self.cond_chain = () self.variables = [] self.variable_counter = itertools.count() self.stack = [] self.on_failure = [] self.push_format_context() # Rewrite assert into a bunch of statements. top_condition, explanation = self.visit(assert_.test) # Create failure message. body = self.on_failure negation = ast.UnaryOp(ast.Not(), top_condition) self.statements.append(ast.If(negation, body, [])) explanation = "assert " + explanation template = ast.Str(explanation) msg = self.pop_format_context(template) fmt = self.helper("format_explanation", msg) err_name = ast.Name("AssertionError", ast.Load()) if sys.hexversion >= 0x3000000: exc = ast.Call(err_name, [fmt], []) else: exc = ast.Call(err_name, [fmt], [], None, None) if sys.version_info[0] >= 3: raise_ = ast.Raise(exc, None) else: raise_ = ast.Raise(exc, None, None) body.append(raise_) # Clear temporary variables by setting them to None. if self.variables: variables = [ ast.Name(name, ast.Store()) for name in self.variables ] clear = ast.Assign(variables, ast.Name("None", ast.Load())) self.statements.append(clear) # Fix line numbers. for stmt in self.statements: set_location(stmt, assert_.lineno, assert_.col_offset) return self.statements
def visit_ImportFrom(self, node): if node.module == self.import_name: replacement = ast.Raise(exc=ast.Call( func=ast.Name(id='ImportError', ctx=ast.Load()), args=[], keywords=[], ), cause=None) return ast.copy_location(replacement, node) else: return node
def r_single_keyword_stmt(node: ast.Name, ctx: Context, rule_type): if rule_type == ast.Yield: new_node = ast.Yield(value=None) elif rule_type == ast.Raise: new_node = ast.Raise(exc=None, cause=None) else: new_node = rule_type() return copy_lineinfo(node, new_node)
def visit_Raise(self, node): if isinstance(node.exc, gast.Call) and \ isinstance(node.exc.func, gast.Attribute) and \ node.exc.func.attr == 'with_traceback': raised = self._visit(node.exc.func.value) traceback = self._visit(node.exc.args[0]) else: raised = self._visit(node.exc) traceback = None new_node = ast.Raise(raised, None, traceback) ast.copy_location(new_node, node) return new_node
def visit_Raise(self, node): if isinstance(node.exc, ast.Name): import builtins exc_cls = getattr(builtins, node.exc.id, None) if isinstance(exc_cls, type) and issubclass(exc_cls, BaseException): return self.visit(ast.copy_location( ast.Raise( exc=ast.Call(func=node.exc, args=[], keywords=[]), cause=node.cause ), node )) return self.generic_visit(node)
def raise_type_violation_error_ast(variable_name, expected_type): return ast.Raise( exc=ast.Call( func=load('TypeViolationError'), args=[ ast.Str(s=variable_name), load(expected_type), type_ast(variable_name), ], keywords=[], ), cause=None, )
def arg_check(bs, args, should): if map(id, args) == map(id, should): return False import mypyable bs.this.append( ast.Raise( type=ast.Call( func=mypyable.TypeError_impl.load, args=[ast.Str(s="expected %r, got %r" % (should, args))], keywords=[], starargs=None, kwargs=None, ), inst=None, tback=None, ), ) return True
def test_wrong_arg(self): bad = ast.Raise() # doesn't matter what is inside args = ast.arguments(args=[bad], defaults=[]) the_ast = ast.FunctionDef(name="haha", args=args, body=[], decorator_list=[]) if sys.version_info < (2, 7): self.assertRaises(support.schema.SchemaError, self.make_verification_callable(the_ast)) else: with self.capture_error() as cap: self.schema.verify(the_ast) self.assertIn(str(cap.exception), [ "At arguments.args[0]: Cannot be a Raise", "At arguments.args[0]: Expecting arg but got Raise" ])
def t_wrap_try_catch(the_ast, uid=1): if len(the_ast.body) == 0 or not isinstance(the_ast.body[0], ast.FunctionDef): return False, the_ast temp = ast.Try(body=the_ast.body[0].body, handlers=[ ast.ExceptHandler(type=ast.Name(id='Exception', ctx=ast.Load()), name='REPLACME' + str(uid), body=[ast.Raise()]) ], orelse=[], finalbody=[]) the_ast.body[0].body = [temp] return True, the_ast
def visit_Return(self, node: ast.Return): if isinstance(node.value, ast.Tuple): rhs_length = len(node.value.elts) else: rhs_length = 1 if isinstance(self.target_node, ast.Tuple): lhs_length = len(self.target_node.elts) else: lhs_length = 1 if lhs_length == rhs_length: return ast.Assign( targets=[self.target_node], value=node.value, lineno=node.lineno, col_offset=node.col_offset, ) else: return ast.Raise(lineno=node.lineno, col_offset=node.col_offset)
def raise_exception(self, node, exc=None, msg='', expr=None, lineno=None): """Add an exception.""" if self.error is None: self.error = [] if expr is None: expr = self.expr if len(self.error) > 0 and not isinstance(node, ast.Module): msg = '%s' % msg err = ExceptionHolder(node, exc=exc, msg=msg, expr=expr, lineno=lineno) self._interrupt = ast.Raise() self.error.append(err) if self.error_msg is None: self.error_msg = "at expr='%s'" % (self.expr) elif len(msg) > 0: self.error_msg = msg if exc is None: try: exc = self.error[0].exc except: exc = RuntimeError raise exc(self.error_msg)
def setter_body(item): """Construct the body of the setter function. """ new_value = Name(id="new", ctx=ast.Load()) inst_var = Attribute(value=Name(id="self", ctx=ast.Load()), attr=f"_{item.var}", ctx=ast.Store()) comp_node = Compare( left=Num(n=item.lower), ops=[ast.Lt(), ast.Lt()], comparators=[new_value, Num(n=item.upper)], ) assign_stmt = ast.Assign(targets=[inst_var], value=new_value) except_msg = f"value outside of range {item.lower} < {item.var} < {item.upper}" exc = ast.Call( func=Name(id="ValueError", ctx=ast.Load()), args=[ast.Str(s=except_msg)], keywords=[], ) else_body = ast.Raise(exc=exc, cause=None) if_node = ast.If(test=comp_node, body=[assign_stmt], orelse=[else_body]) return if_node