@@ -280,6 +280,55 @@ typedef struct {
280
280
PyObject * exception_traceback ; /* Stored exception traceback */
281
281
} CallState ;
282
282
283
+ /**
284
+ * @brief Compatibility layer for Python exception handling API changes.
285
+ * PyErr_Fetch was deprecated in Python 3.12 in favor of PyErr_GetRaisedException.
286
+ */
287
+ #if PY_VERSION_HEX >= 0x030c0000
288
+ /* Python 3.12+ - use new API */
289
+ static inline void
290
+ CallState_fetch_exception (CallState * cs ) {
291
+ PyObject * exc = PyErr_GetRaisedException ();
292
+ if (exc ) {
293
+ cs -> exception_type = (PyObject * )Py_TYPE (exc );
294
+ Py_INCREF (cs -> exception_type );
295
+ cs -> exception_value = exc ;
296
+ cs -> exception_traceback = PyException_GetTraceback (exc );
297
+ } else {
298
+ cs -> exception_type = NULL ;
299
+ cs -> exception_value = NULL ;
300
+ cs -> exception_traceback = NULL ;
301
+ }
302
+ }
303
+
304
+ static inline void
305
+ CallState_restore_exception (CallState * cs ) {
306
+ if (cs -> exception_value ) {
307
+ PyErr_SetRaisedException (cs -> exception_value );
308
+ /* PyErr_SetRaisedException steals the reference, so clear our pointer */
309
+ cs -> exception_value = NULL ;
310
+ Py_XDECREF (cs -> exception_type );
311
+ cs -> exception_type = NULL ;
312
+ Py_XDECREF (cs -> exception_traceback );
313
+ cs -> exception_traceback = NULL ;
314
+ }
315
+ }
316
+ #else
317
+ /* Python < 3.12 - use legacy API */
318
+ static inline void
319
+ CallState_fetch_exception (CallState * cs ) {
320
+ PyErr_Fetch (& cs -> exception_type , & cs -> exception_value , & cs -> exception_traceback );
321
+ }
322
+
323
+ static inline void
324
+ CallState_restore_exception (CallState * cs ) {
325
+ PyErr_Restore (cs -> exception_type , cs -> exception_value , cs -> exception_traceback );
326
+ cs -> exception_type = NULL ;
327
+ cs -> exception_value = NULL ;
328
+ cs -> exception_traceback = NULL ;
329
+ }
330
+ #endif
331
+
283
332
/**
284
333
* @brief Initialiase a CallState and unlock the GIL prior to a
285
334
* possibly blocking external call.
0 commit comments