From ede049b2d322f160814133677427f7ea0f2ee639 Mon Sep 17 00:00:00 2001 From: Jeremy Hylton Date: Wed, 26 Sep 2001 20:01:13 +0000 Subject: Add tests for new PyErr_NormalizeException() behavior Add raise_exception() to the _testcapi module. It isn't a test, but the C API exists only to support test_exceptions. raise_exception() takes two arguments -- an exception class and an integer specifying how many arguments it should be called with. test_exceptions uses BadException() to test the interpreter's behavior when there is a problem instantiating the exception. test_capi1() calls it with too many arguments. test_capi2() causes an exception to be raised in the Python code of the constructor. --- Lib/test/test_exceptions.py | 35 +++++++++++++++++++++++++++++++++++ Modules/_testcapimodule.c | 26 ++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) 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}, -- cgit v0.12