summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Behnel <stefan_ml@behnel.de>2013-11-23 08:50:14 +0100
committerStefan Behnel <stefan_ml@behnel.de>2013-11-23 08:50:14 +0100
commita6195f1a44ab21f5aa4b2a1b1842dd93115a3f42 (patch)
tree3b252cc8c30b45705e23bbaa056bf87f5a026eda
parent0c6fdf066588732f96d0f90eeace517de7a91f42 (diff)
downloadcython-a6195f1a44ab21f5aa4b2a1b1842dd93115a3f42.tar.gz
let CPython do the exception instantiation on 'raise' in Py3 to make sure we handle all special cases correctly
-rw-r--r--Cython/Utility/Exceptions.c22
-rw-r--r--tests/run/reraise_3args.pyx23
2 files changed, 25 insertions, 20 deletions
diff --git a/Cython/Utility/Exceptions.c b/Cython/Utility/Exceptions.c
index 3c3b64221..917f36618 100644
--- a/Cython/Utility/Exceptions.c
+++ b/Cython/Utility/Exceptions.c
@@ -135,7 +135,6 @@ raise_error:
#else /* Python 3+ */
static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
- PyObject* owned_instance = NULL;
if (tb == Py_None) {
tb = 0;
} else if (tb && !PyTraceBack_Check(tb)) {
@@ -143,11 +142,9 @@ static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject
"raise: arg 3 must be a traceback or None");
goto bad;
}
- if (value == Py_None)
- value = 0;
if (PyExceptionInstance_Check(type)) {
- if (value) {
+ if (value && value != Py_None) {
PyErr_SetString(PyExc_TypeError,
"instance exception may not have a separate value");
goto bad;
@@ -156,21 +153,7 @@ static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject
type = (PyObject*) Py_TYPE(value);
} else if (PyExceptionClass_Check(type)) {
// instantiate the type now (we don't know when and how it will be caught)
- PyObject *args;
- if (!value)
- args = PyTuple_New(0);
- else if (PyTuple_Check(value)) {
- Py_INCREF(value);
- args = value;
- } else
- args = PyTuple_Pack(1, value);
- if (!args)
- goto bad;
- owned_instance = PyEval_CallObject(type, args);
- Py_DECREF(args);
- if (!owned_instance)
- goto bad;
- value = owned_instance;
+ PyErr_NormalizeException(&type, &value, &tb);
if (!PyExceptionInstance_Check(value)) {
PyErr_Format(PyExc_TypeError,
"calling %R should have returned an instance of "
@@ -222,7 +205,6 @@ static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject
}
bad:
- Py_XDECREF(owned_instance);
return;
}
#endif
diff --git a/tests/run/reraise_3args.pyx b/tests/run/reraise_3args.pyx
new file mode 100644
index 000000000..a892efe48
--- /dev/null
+++ b/tests/run/reraise_3args.pyx
@@ -0,0 +1,23 @@
+
+import sys
+
+
+class MyError(Exception):
+ def __init__(self, name, var):
+ self.name = name
+ self.var = var
+
+
+def reraise_explicitly():
+ """
+ >>> try: reraise_explicitly()
+ ... except MyError: print("RAISED!")
+ ... else: print("NOT RAISED!")
+ RAISED!
+ """
+ try:
+ raise MyError('Oh no!', 42)
+ except MyError:
+ tmp = sys.exc_info()
+
+ raise tmp[0], tmp[1], tmp[2]