summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/test/test_exceptions.py35
-rw-r--r--Modules/_testcapimodule.c26
2 files changed, 61 insertions, 0 deletions
diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py
index 104258a..d194c8b 100644
--- a/Lib/test/test_exceptions.py
+++ b/Lib/test/test_exceptions.py
@@ -3,6 +3,8 @@
from test_support import *
from types import ClassType
import warnings
+import sys, traceback
+import _testcapi
warnings.filterwarnings("error", "", OverflowWarning, __name__)
@@ -161,4 +163,37 @@ r(Exception)
try: x = 1/0
except Exception, e: pass
+# test that setting an exception at the C level works even if the
+# exception object can't be constructed.
+
+class BadException:
+ def __init__(self):
+ raise RuntimeError, "can't instantiate BadException"
+
+def test_capi1():
+ try:
+ _testcapi.raise_exception(BadException, 1)
+ except TypeError, err:
+ exc, err, tb = sys.exc_info()
+ co = tb.tb_frame.f_code
+ assert co.co_name == "test_capi1"
+ assert co.co_filename.endswith('test_exceptions.py')
+ else:
+ print "Expected exception"
+test_capi1()
+
+def test_capi2():
+ try:
+ _testcapi.raise_exception(BadException, 0)
+ except RuntimeError, err:
+ exc, err, tb = sys.exc_info()
+ co = tb.tb_frame.f_code
+ assert co.co_name == "__init__"
+ assert co.co_filename.endswith('test_exceptions.py')
+ co2 = tb.tb_frame.f_back.f_code
+ assert co2.co_name == "test_capi2"
+ else:
+ print "Expected exception"
+test_capi2()
+
unlink(TESTFN)
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index e8db847..1a875f7 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -257,8 +257,34 @@ test_longlong_api(PyObject* self, PyObject* args)
#endif /* ifdef HAVE_LONG_LONG */
+static PyObject *
+raise_exception(PyObject *self, PyObject *args)
+{
+ PyObject *exc;
+ PyObject *exc_args, *v;
+ int num_args, i;
+
+ if (!PyArg_ParseTuple(args, "Oi:raise_exception",
+ &exc, &num_args))
+ return NULL;
+
+ exc_args = PyTuple_New(num_args);
+ if (exc_args == NULL)
+ return NULL;
+ for (i = 0; i < num_args; ++i) {
+ v = PyInt_FromLong(i);
+ if (v == NULL) {
+ Py_DECREF(exc_args);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(exc_args, i, v);
+ }
+ PyErr_SetObject(exc, exc_args);
+ return NULL;
+}
static PyMethodDef TestMethods[] = {
+ {"raise_exception", raise_exception, METH_VARARGS},
{"test_config", test_config, METH_VARARGS},
{"test_list_api", test_list_api, METH_VARARGS},
{"test_dict_iteration", test_dict_iteration, METH_VARARGS},