def exc_from_raise(self, w_arg1, w_arg2): """ Create a wrapped exception from the arguments of a raise statement. Returns an FSException object whose w_value is an instance of w_type. """ w_is_type = op.simple_call(const(isinstance), w_arg1, const(type)).eval(self) if self.guessbool(w_is_type): # this is for all cases of the form (Class, something) if self.guessbool(op.is_(w_arg2, w_None).eval(self)): # raise Type: we assume we have to instantiate Type w_value = op.simple_call(w_arg1).eval(self) else: w_valuetype = op.type(w_arg2).eval(self) if self.guessbool(op.issubtype(w_valuetype, w_arg1).eval(self)): # raise Type, Instance: let etype be the exact type of value w_value = w_arg2 else: # raise Type, X: assume X is the constructor argument w_value = op.simple_call(w_arg1, w_arg2).eval(self) else: # the only case left here is (inst, None), from a 'raise inst'. if not self.guessbool(op.is_(w_arg2, const(None)).eval(self)): exc = TypeError("instance exception may not have a " "separate value") raise Raise(const(exc)) w_value = w_arg1 w_type = op.type(w_value).eval(self) return FSException(w_type, w_value)
def exception_match(self, w_exc_type, w_check_class): """Checks if the given exception type matches 'w_check_class'.""" if not isinstance(w_check_class, Constant): raise FlowingError("Non-constant except guard.") check_class = w_check_class.value if check_class in (NotImplementedError, AssertionError): raise FlowingError( "Catching %s is not valid in RPython" % check_class.__name__) if not isinstance(check_class, tuple): # the simple case return self.guessbool(op.issubtype(w_exc_type, w_check_class).eval(self)) # special case for StackOverflow (see rlib/rstackovf.py) if check_class == rstackovf.StackOverflow: w_real_class = const(rstackovf._StackOverflow) return self.guessbool(op.issubtype(w_exc_type, w_real_class).eval(self)) # checking a tuple of classes for klass in w_check_class.value: if self.exception_match(w_exc_type, const(klass)): return True return False