Skip to content

Commit e693fac

Browse files
committed
Add wrapper for depreciated API
1 parent 5f29f12 commit e693fac

File tree

5 files changed

+44
-39
lines changed

5 files changed

+44
-39
lines changed

src/confluent_kafka/src/Admin.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5082,7 +5082,7 @@ static void Admin_background_event_cb (rd_kafka_t *rk, rd_kafka_event_t *rkev,
50825082
PyObject *trace = NULL;
50835083

50845084
/* Fetch (and clear) currently raised exception */
5085-
PyErr_Fetch(&exctype, &error, &trace);
5085+
cfl_exception_fetch(&exctype, &exc, &trace);
50865086
Py_XDECREF(trace);
50875087
}
50885088

src/confluent_kafka/src/Consumer.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1576,7 +1576,7 @@ static void Consumer_rebalance_cb (rd_kafka_t *rk, rd_kafka_resp_err_t err,
15761576
Py_DECREF(result);
15771577
else {
15781578

1579-
PyErr_Fetch(&cs->exception_type, &cs->exception_value, &cs->exception_traceback);
1579+
CallState_fetch_exception(cs);
15801580
CallState_crash(cs);
15811581
rd_kafka_yield(rk);
15821582
}

src/confluent_kafka/src/Producer.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ static void dr_msg_cb (rd_kafka_t *rk, const rd_kafka_message_t *rkm,
164164
Py_DECREF(result);
165165
else {
166166

167-
PyErr_Fetch(&cs->exception_type, &cs->exception_value, &cs->exception_traceback);
167+
CallState_fetch_exception(cs);
168168
CallState_crash(cs);
169169
rd_kafka_yield(rk);
170170
}

src/confluent_kafka/src/confluent_kafka.c

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1756,7 +1756,7 @@ static void error_cb (rd_kafka_t *rk, int err, const char *reason, void *opaque)
17561756
Py_DECREF(result);
17571757
else {
17581758

1759-
PyErr_Fetch(&cs->exception_type, &cs->exception_value, &cs->exception_traceback);
1759+
CallState_fetch_exception(cs);
17601760
crash:
17611761
CallState_crash(cs);
17621762
rd_kafka_yield(h->rk);
@@ -1811,7 +1811,7 @@ static void throttle_cb (rd_kafka_t *rk, const char *broker_name, int32_t broker
18111811
Py_DECREF(result);
18121812
goto done;
18131813
} else {
1814-
PyErr_Fetch(&cs->exception_type, &cs->exception_value, &cs->exception_traceback);
1814+
CallState_fetch_exception(cs);
18151815
}
18161816

18171817
/**
@@ -1843,7 +1843,7 @@ static int stats_cb(rd_kafka_t *rk, char *json, size_t json_len, void *opaque) {
18431843
if (result)
18441844
Py_DECREF(result);
18451845
else {
1846-
PyErr_Fetch(&cs->exception_type, &cs->exception_value, &cs->exception_traceback);
1846+
CallState_fetch_exception(cs);
18471847
CallState_crash(cs);
18481848
rd_kafka_yield(h->rk);
18491849
}
@@ -1879,7 +1879,7 @@ static void log_cb (const rd_kafka_t *rk, int level,
18791879
if (result)
18801880
Py_DECREF(result);
18811881
else {
1882-
PyErr_Fetch(&cs->exception_type, &cs->exception_value, &cs->exception_traceback);
1882+
CallState_fetch_exception(cs);
18831883
CallState_crash(cs);
18841884
rd_kafka_yield(h->rk);
18851885
}
@@ -2607,10 +2607,7 @@ int CallState_end (Handle *h, CallState *cs) {
26072607
if (cs->crashed) {
26082608
/* Restore the saved exception if we have one */
26092609
if (cs->exception_type) {
2610-
PyErr_Restore(cs->exception_type, cs->exception_value, cs->exception_traceback);
2611-
cs->exception_type = NULL;
2612-
cs->exception_value = NULL;
2613-
cs->exception_traceback = NULL;
2610+
CallState_restore_exception(cs);
26142611
}
26152612
return 0;
26162613
}

src/confluent_kafka/src/confluent_kafka.h

Lines changed: 36 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -282,52 +282,60 @@ typedef struct {
282282

283283
/**
284284
* @brief Compatibility layer for Python exception handling API changes.
285-
* PyErr_Fetch was deprecated in Python 3.12 in favor of PyErr_GetRaisedException.
285+
* PyErr_Fetch/PyErr_Restore were deprecated in Python 3.12 in favor of
286+
* PyErr_GetRaisedException/PyErr_SetRaisedException.
286287
*/
287-
#if PY_VERSION_HEX >= 0x030c0000
288-
/* Python 3.12+ - use new API */
288+
289+
/* General-purpose compatibility wrappers */
289290
static inline void
290-
CallState_fetch_exception(CallState *cs) {
291+
cfl_exception_fetch(PyObject **exc_type, PyObject **exc_value, PyObject **exc_traceback) {
292+
#if PY_VERSION_HEX >= 0x030c0000
293+
/* Python 3.12+ - use new API */
291294
PyObject *exc = PyErr_GetRaisedException();
292295
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);
296+
*exc_type = (PyObject *)Py_TYPE(exc);
297+
Py_INCREF(*exc_type);
298+
*exc_value = exc;
299+
*exc_traceback = PyException_GetTraceback(exc);
297300
} else {
298-
cs->exception_type = NULL;
299-
cs->exception_value = NULL;
300-
cs->exception_traceback = NULL;
301+
*exc_type = *exc_value = *exc_traceback = NULL;
301302
}
303+
#else
304+
/* Python < 3.12 - use legacy API */
305+
PyErr_Fetch(exc_type, exc_value, exc_traceback);
306+
#endif
302307
}
303308

304309
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;
310+
cfl_exception_restore(PyObject *exc_type, PyObject *exc_value, PyObject *exc_traceback) {
311+
#if PY_VERSION_HEX >= 0x030c0000
312+
/* Python 3.12+ - use new API */
313+
if (exc_value) {
314+
PyErr_SetRaisedException(exc_value);
315+
Py_XDECREF(exc_type);
316+
Py_XDECREF(exc_traceback);
314317
}
315-
}
316318
#else
317-
/* Python < 3.12 - use legacy API */
319+
/* Python < 3.12 - use legacy API */
320+
PyErr_Restore(exc_type, exc_value, exc_traceback);
321+
#endif
322+
}
323+
324+
/* CallState-specific convenience wrappers */
318325
static inline void
319326
CallState_fetch_exception(CallState *cs) {
320-
PyErr_Fetch(&cs->exception_type, &cs->exception_value, &cs->exception_traceback);
327+
cfl_exception_fetch(&cs->exception_type, &cs->exception_value, &cs->exception_traceback);
321328
}
322329

323330
static inline void
324331
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;
332+
if (cs->exception_type) {
333+
cfl_exception_restore(cs->exception_type, cs->exception_value, cs->exception_traceback);
334+
cs->exception_type = NULL;
335+
cs->exception_value = NULL;
336+
cs->exception_traceback = NULL;
337+
}
329338
}
330-
#endif
331339

332340
/**
333341
* @brief Initialiase a CallState and unlock the GIL prior to a

0 commit comments

Comments
 (0)