Commit 5b46bcfc authored by Stefan Behnel's avatar Stefan Behnel

merge 0.19.x branch into master

parents bcd7eff4 60eb977a
...@@ -135,7 +135,7 @@ raise_error: ...@@ -135,7 +135,7 @@ raise_error:
#else /* Python 3+ */ #else /* Python 3+ */
static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
PyObject *owned_type = NULL, *owned_value = NULL, *owned_tb = NULL; PyObject* owned_instance = NULL;
if (tb == Py_None) { if (tb == Py_None) {
tb = 0; tb = 0;
} else if (tb && !PyTraceBack_Check(tb)) { } else if (tb && !PyTraceBack_Check(tb)) {
...@@ -143,9 +143,11 @@ static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject ...@@ -143,9 +143,11 @@ static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject
"raise: arg 3 must be a traceback or None"); "raise: arg 3 must be a traceback or None");
goto bad; goto bad;
} }
if (value == Py_None)
value = 0;
if (PyExceptionInstance_Check(type)) { if (PyExceptionInstance_Check(type)) {
if (value && value != Py_None) { if (value) {
PyErr_SetString(PyExc_TypeError, PyErr_SetString(PyExc_TypeError,
"instance exception may not have a separate value"); "instance exception may not have a separate value");
goto bad; goto bad;
...@@ -153,18 +155,45 @@ static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject ...@@ -153,18 +155,45 @@ static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject
value = type; value = type;
type = (PyObject*) Py_TYPE(value); type = (PyObject*) Py_TYPE(value);
} else if (PyExceptionClass_Check(type)) { } else if (PyExceptionClass_Check(type)) {
// instantiate the type now (we don't know when and how it will be caught) // make sure value is an exception instance of type
PyErr_NormalizeException(&type, &value, &owned_tb); PyObject *instance_class = NULL;
if (!tb && owned_tb) if (value && PyExceptionInstance_Check(value)) {
tb = owned_tb; instance_class = (PyObject*) Py_TYPE(value);
owned_type = type; if (instance_class != type) {
owned_value = value; if (PyObject_IsSubclass(instance_class, type)) {
if (!PyExceptionInstance_Check(value)) { // believe the instance
PyErr_Format(PyExc_TypeError, type = instance_class;
"calling %R should have returned an instance of " } else {
"BaseException, not %R", instance_class = NULL;
type, Py_TYPE(value)); }
goto bad; }
}
if (!instance_class) {
// instantiate the type now (we don't know when and how it will be caught)
// assuming that 'value' is an argument to the type's constructor
// not using PyErr_NormalizeException() to avoid ref-counting problems
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 = PyObject_Call(type, args, NULL);
Py_DECREF(args);
if (!owned_instance)
goto bad;
value = owned_instance;
if (!PyExceptionInstance_Check(value)) {
PyErr_Format(PyExc_TypeError,
"calling %R should have returned an instance of "
"BaseException, not %R",
type, Py_TYPE(value));
goto bad;
}
} }
} else { } else {
PyErr_SetString(PyExc_TypeError, PyErr_SetString(PyExc_TypeError,
...@@ -210,10 +239,7 @@ static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject ...@@ -210,10 +239,7 @@ static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject
} }
bad: bad:
Py_XDECREF(owned_type); Py_XDECREF(owned_instance);
Py_XDECREF(owned_value);
Py_XDECREF(owned_tb);
return; return;
} }
#endif #endif
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
cimport cython cimport cython
@cython.test_assert_path_exists( @cython.test_assert_path_exists(
'//RaiseStatNode', '//RaiseStatNode',
'//RaiseStatNode[@builtin_exc_name = "MemoryError"]') '//RaiseStatNode[@builtin_exc_name = "MemoryError"]')
...@@ -13,6 +14,7 @@ def raise_me_type(): ...@@ -13,6 +14,7 @@ def raise_me_type():
""" """
raise MemoryError raise MemoryError
@cython.test_assert_path_exists( @cython.test_assert_path_exists(
'//RaiseStatNode', '//RaiseStatNode',
'//RaiseStatNode[@builtin_exc_name = "MemoryError"]') '//RaiseStatNode[@builtin_exc_name = "MemoryError"]')
...@@ -24,6 +26,7 @@ def raise_me_instance(): ...@@ -24,6 +26,7 @@ def raise_me_instance():
""" """
raise MemoryError() raise MemoryError()
def raise_me_instance_value(): def raise_me_instance_value():
""" """
>>> raise_me_instance_value() >>> raise_me_instance_value()
...@@ -32,3 +35,13 @@ def raise_me_instance_value(): ...@@ -32,3 +35,13 @@ def raise_me_instance_value():
MemoryError: oom MemoryError: oom
""" """
raise MemoryError("oom") raise MemoryError("oom")
def raise_me_instance_value_separate():
"""
>>> raise_me_instance_value_separate()
Traceback (most recent call last):
...
MemoryError: oom
"""
raise MemoryError, "oom"
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment