]> granicus.if.org Git - python/commitdiff
Add tests for new PyErr_NormalizeException() behavior
authorJeremy Hylton <jeremy@alum.mit.edu>
Wed, 26 Sep 2001 20:01:13 +0000 (20:01 +0000)
committerJeremy Hylton <jeremy@alum.mit.edu>
Wed, 26 Sep 2001 20:01:13 +0000 (20:01 +0000)
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
Modules/_testcapimodule.c

index 104258a549dfe7b6bba381b7f377b39633c69b8b..d194c8b030e35cf3dd498d8d53cb1778133f9849 100644 (file)
@@ -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)
index e8db847176ef4dc021e7bff3f2c23652473db87a..1a875f77c0167f8b8df61b82a29a90c426ab6f0a 100644 (file)
@@ -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},