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.
This commit is contained in:
Jeremy Hylton 2001-09-26 20:01:13 +00:00
parent e2e2c9f41e
commit ede049b2d3
2 changed files with 61 additions and 0 deletions

View File

@ -3,6 +3,8 @@
from test_support import * from test_support import *
from types import ClassType from types import ClassType
import warnings import warnings
import sys, traceback
import _testcapi
warnings.filterwarnings("error", "", OverflowWarning, __name__) warnings.filterwarnings("error", "", OverflowWarning, __name__)
@ -161,4 +163,37 @@ r(Exception)
try: x = 1/0 try: x = 1/0
except Exception, e: pass 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) unlink(TESTFN)

View File

@ -257,8 +257,34 @@ test_longlong_api(PyObject* self, PyObject* args)
#endif /* ifdef HAVE_LONG_LONG */ #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[] = { static PyMethodDef TestMethods[] = {
{"raise_exception", raise_exception, METH_VARARGS},
{"test_config", test_config, METH_VARARGS}, {"test_config", test_config, METH_VARARGS},
{"test_list_api", test_list_api, METH_VARARGS}, {"test_list_api", test_list_api, METH_VARARGS},
{"test_dict_iteration", test_dict_iteration, METH_VARARGS}, {"test_dict_iteration", test_dict_iteration, METH_VARARGS},