@@ -9117,14 +9117,20 @@ releasebuffer_maybe_call_super(PyObject *self, Py_buffer *buffer)
9117
9117
static void
9118
9118
releasebuffer_call_python (PyObject * self , Py_buffer * buffer )
9119
9119
{
9120
+ // bf_releasebuffer may be called while an exception is already active.
9121
+ // We have no way to report additional errors up the stack, because
9122
+ // this slot returns void, so we simply stash away the active exception
9123
+ // and restore it after the call to Python returns.
9124
+ PyObject * exc = PyErr_GetRaisedException ();
9125
+
9120
9126
PyObject * mv ;
9121
9127
bool is_buffer_wrapper = Py_TYPE (buffer -> obj ) == & _PyBufferWrapper_Type ;
9122
9128
if (is_buffer_wrapper ) {
9123
9129
// Make sure we pass the same memoryview to
9124
9130
// __release_buffer__() that __buffer__() returned.
9125
9131
PyBufferWrapper * bw = (PyBufferWrapper * )buffer -> obj ;
9126
9132
if (bw -> mv == NULL ) {
9127
- return ;
9133
+ goto end ;
9128
9134
}
9129
9135
mv = Py_NewRef (bw -> mv );
9130
9136
}
@@ -9134,7 +9140,7 @@ releasebuffer_call_python(PyObject *self, Py_buffer *buffer)
9134
9140
mv = PyMemoryView_FromBuffer (buffer );
9135
9141
if (mv == NULL ) {
9136
9142
PyErr_WriteUnraisable (self );
9137
- return ;
9143
+ goto end ;
9138
9144
}
9139
9145
// Set the memoryview to restricted mode, which forbids
9140
9146
// users from saving any reference to the underlying buffer
@@ -9155,6 +9161,10 @@ releasebuffer_call_python(PyObject *self, Py_buffer *buffer)
9155
9161
PyObject_CallMethodNoArgs (mv , & _Py_ID (release ));
9156
9162
}
9157
9163
Py_DECREF (mv );
9164
+ end :
9165
+ assert (!PyErr_Occurred ());
9166
+
9167
+ PyErr_SetRaisedException (exc );
9158
9168
}
9159
9169
9160
9170
/*
0 commit comments