Author: Amaury Forgeot d'Arc <[email protected]>
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
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit