Author: Amaury Forgeot d'Arc <amaur...@gmail.com> Branch: py3k Changeset: r48032:47a171031fd3 Date: 2011-10-13 22:38 +0200 http://bitbucket.org/pypy/pypy/changeset/47a171031fd3/
Log: Add Exception.__cause__ and __context__ diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -491,7 +491,7 @@ w_value = w_cause = space.w_None if nbargs >= 2: - w_cause = self.popvalue() # XXX cause? + w_cause = self.popvalue() if 1: w_value = self.popvalue() if space.exception_is_valid_obj_as_class_w(w_value): @@ -499,6 +499,7 @@ w_value = space.call_function(w_type) else: w_type = space.type(w_value) + w_value.w_cause = w_cause operror = OperationError(w_type, w_value) operror.normalize_exception(space) w_traceback = space.w_None # XXX with_traceback? diff --git a/pypy/module/exceptions/interp_exceptions.py b/pypy/module/exceptions/interp_exceptions.py --- a/pypy/module/exceptions/interp_exceptions.py +++ b/pypy/module/exceptions/interp_exceptions.py @@ -95,6 +95,8 @@ """ w_dict = None args_w = [] + w_cause = None + w_context = None def __init__(self, space): self.w_message = space.w_None @@ -145,6 +147,28 @@ def descr_setargs(self, space, w_newargs): self.args_w = space.fixedview(w_newargs) + def descr_getcause(self, space): + return self.w_cause + + def descr_setcause(self, space, w_newcause): + if not (space.is_w(w_newcause, space.w_None) or + space.exception_is_valid_class_w(space.type(w_newcause))): + raise OperationError(space.w_TypeError, space.wrap( + "exception cause must be None or " + "derive from BaseException")) + self.w_cause = w_newcause + + def descr_getcontext(self, space): + return self.w_context + + def descr_setcontext(self, space, w_newcontext): + if not (space.is_w(w_newcontext, space.w_None) or + space.exception_is_valid_class_w(space.type(w_newcontext))): + raise OperationError(space.w_TypeError, space.wrap( + "exception context must be None or " + "derive from BaseException")) + self.w_context = w_newcontext + def descr_getitem(self, space, w_index): return space.getitem(space.newtuple(self.args_w), w_index) @@ -223,6 +247,10 @@ W_BaseException.descr_message_del), args = GetSetProperty(W_BaseException.descr_getargs, W_BaseException.descr_setargs), + __cause__ = GetSetProperty(W_BaseException.descr_getcause, + W_BaseException.descr_setcause), + __context__ = GetSetProperty(W_BaseException.descr_getcontext, + W_BaseException.descr_setcontext), ) def _new_exception(name, base, docstring, **kwargs): diff --git a/pypy/module/exceptions/test/test_exc.py b/pypy/module/exceptions/test/test_exc.py --- a/pypy/module/exceptions/test/test_exc.py +++ b/pypy/module/exceptions/test/test_exc.py @@ -241,3 +241,23 @@ assert fw.z == 1 assert fw.xyz == (1, 2) + def test_cause(self): + e1 = TypeError() + e2 = ValueError() + assert e1.__cause__ is None + e1.__cause__ = e2 + assert e1.__cause__ is e2 + e1.__cause__ = None + raises(TypeError, setattr, e1, '__cause__', 1) + raises(AttributeError, delattr, e1, '__cause__') + + def test_context(self): + e1 = TypeError() + e2 = ValueError() + assert e1.__context__ is None + e1.__context__ = e2 + assert e1.__context__ is e2 + e1.__context__ = None + raises(TypeError, setattr, e1, '__context__', 1) + raises(AttributeError, delattr, e1, '__context__') + _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit