@@ -9115,8 +9115,9 @@ releasebuffer_maybe_call_super(PyObject *self, Py_buffer *buffer)
9115
9115
}
9116
9116
9117
9117
static void
9118
- releasebuffer_call_python (PyObject * self , Py_buffer * buffer )
9118
+ releasebuffer_call_python_inner (PyObject * self , Py_buffer * buffer )
9119
9119
{
9120
+ assert (!PyErr_Occurred ());
9120
9121
PyObject * mv ;
9121
9122
bool is_buffer_wrapper = Py_TYPE (buffer -> obj ) == & _PyBufferWrapper_Type ;
9122
9123
if (is_buffer_wrapper ) {
@@ -9157,6 +9158,22 @@ releasebuffer_call_python(PyObject *self, Py_buffer *buffer)
9157
9158
Py_DECREF (mv );
9158
9159
}
9159
9160
9161
+ static void
9162
+ releasebuffer_call_python (PyObject * self , Py_buffer * buffer )
9163
+ {
9164
+ // bf_releasebuffer may be called while an exception is already active.
9165
+ // We have no way to report additional errors up the stack, because
9166
+ // this slot returns void, so we simply stash away the active exception
9167
+ // and restore it after the call to Python returns.
9168
+ PyObject * type , * value , * traceback ;
9169
+ PyErr_Fetch (& type , & value , & traceback );
9170
+
9171
+ releasebuffer_call_python_inner (self , buffer );
9172
+ assert (!PyErr_Occurred ());
9173
+
9174
+ PyErr_Restore (type , value , traceback );
9175
+ }
9176
+
9160
9177
/*
9161
9178
* bf_releasebuffer is very delicate, because we need to ensure that
9162
9179
* C bf_releasebuffer slots are called correctly (or we'll leak memory),
0 commit comments