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 copy(self): "Make a copy of this state in which all Variables are fresh." exc = self.last_exception if exc is not None: exc = FSException(_copy(exc.w_type), _copy(exc.w_value)) return FrameState(map(_copy, self.locals_w), map(_copy, self.stack), exc, self.blocklist, self.next_offset)
def guessexception(self, ctx, *classes): assert self.index == len(self.listtoreplay) ctx.recorder = self.nextreplayer outcome = self.booloutcome if outcome is not None: egg = self.nextreplayer.crnt_block w_exc_cls, w_exc_value = egg.inputargs[-2:] if isinstance(egg.last_exception, Constant): w_exc_cls = egg.last_exception assert not isinstance(w_exc_cls.value, list) raise RaiseImplicit(FSException(w_exc_cls, w_exc_value))
def setstate(self, state): """ Reset the context to the given frame state. """ data = state.mergeable[:] recursively_unflatten(data) self.restore_locals_stack(data[:-2]) # Nones == undefined locals if data[-2] == Constant(None): assert data[-1] == Constant(None) self.last_exception = None else: self.last_exception = FSException(data[-2], data[-1]) self.blockstack = state.blocklist[:]
def union(self, other): """Compute a state that is at least as general as both self and other. A state 'a' is more general than a state 'b' if all Variables in 'b' are also Variables in 'a', but 'a' may have more Variables. """ try: locals = _union(self.locals_w, other.locals_w) stack = _union(self.stack, other.stack) if self.last_exception is None and other.last_exception is None: exc = None else: args1 = self._exc_args() args2 = other._exc_args() exc = FSException(union(args1[0], args2[0]), union(args1[1], args2[1])) except UnionError: return None return FrameState(locals, stack, exc, self.blocklist, self.next_offset)
def rebuild(cls, w_type, w_value): return cls(FSException(w_type, w_value))
def state_pack_variables(w_type, w_value): return Raise(FSException(w_type, w_value))
""" Unit tests for flowcontext.py """ import pytest from rpython.flowspace.model import Variable, FSException from rpython.flowspace.flowcontext import (Return, Raise, RaiseImplicit, Continue, Break) @pytest.mark.parametrize('signal', [ Return(Variable()), Raise(FSException(Variable(), Variable())), RaiseImplicit(FSException(Variable(), Variable())), Break(), Continue(42), ]) def test_signals(signal): assert signal.rebuild(*signal.args) == signal