Skip to content

Commit 8071e2d

Browse files
committed
bigfile/py: Starting from py3.11 exception state is kept only in exc_value no longer using exc_type and exc_traceback
bigfile/_bigfile.c: In function ‘pybigfile_loadblk’: bigfile/_bigfile.c:616:56: error: ‘_PyErr_StackItem’ {aka ‘struct _err_stackitem’} has no member named ‘exc_type’ 616 | XINC( save_exc_type = set0(&ts->exc_state.exc_type) ); | ^ exc_type and exc_traceback can all be derived from exc_value. See python/cpython@396b58345f81 and python/cpython#89874 for details. -> Rework the code to only use exc_value on py ≥ 3.11 . /reviewed-by @jerome /reviewed-on https://lab.nexedi.com/nexedi/wendelin.core/-/merge_requests/37
1 parent 2bcdb37 commit 8071e2d

1 file changed

Lines changed: 30 additions & 16 deletions

File tree

‎bigfile/_bigfile.c‎

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ static PyObject *pybuf_str;
7777
* https://github.com/python/cpython/commit/ae3087c638 */
7878
#define BIGFILE_USE_PYTS_EXC_INFO (PY_VERSION_HEX >= 0x030700A3)
7979

80+
/* Starting from Python 3.11 exception state is kept only in exc_value without
81+
* exc_type and exc_traceback. https://github.com/python/cpython/commit/396b58345f81 */
82+
#define BIGFILE_PYTS_EXC_INFO_ONLY_EXC_VALUE (PY_VERSION_HEX >= 0x030B0000)
83+
8084

8185
/* like PyObject_New, but fully initializes instance (e.g. calls type ->tp_new) */
8286
#define PyType_New(type, typeobj, args) \
@@ -556,9 +560,9 @@ static int pybigfile_loadblk(BigFile *file, blk_t blk, void *buf)
556560
PyGILState_STATE gstate;
557561
PyThreadState *ts;
558562
PyFrameObject *ts_frame_orig = NULL, *ts_frame = NULL;
559-
PyObject *exc_type, *exc_value, *exc_traceback;
560-
PyObject *save_curexc_type, *save_curexc_value, *save_curexc_traceback;
561-
PyObject *save_exc_type, *save_exc_value, *save_exc_traceback;
563+
PyObject *exc_value, *exc_type = NULL, *exc_traceback = NULL;
564+
PyObject *save_curexc_value, *save_curexc_type, *save_curexc_traceback;
565+
PyObject *save_exc_value, *save_exc_type = NULL, *save_exc_traceback = NULL;
562566
#if BIGFILE_USE_PYTS_EXC_INFO
563567
_PyErr_StackItem *save_exc_info;
564568
#endif
@@ -613,15 +617,17 @@ static int pybigfile_loadblk(BigFile *file, blk_t blk, void *buf)
613617
XINC( save_curexc_traceback = set0(&ts->curexc_traceback) );
614618

615619
#if BIGFILE_USE_PYTS_EXC_INFO
616-
XINC( save_exc_type = set0(&ts->exc_state.exc_type) );
617620
XINC( save_exc_value = set0(&ts->exc_state.exc_value) );
621+
# if !BIGFILE_PYTS_EXC_INFO_ONLY_EXC_VALUE
622+
XINC( save_exc_type = set0(&ts->exc_state.exc_type) );
618623
XINC( save_exc_traceback = set0(&ts->exc_state.exc_traceback) );
624+
# endif
619625
save_exc_info = ts->exc_info;
620626
ts->exc_info = &ts->exc_state;
621627
BUG_ON(ts->exc_state.previous_item != NULL);
622628
#else
623-
XINC( save_exc_type = set0(&ts->exc_type) );
624629
XINC( save_exc_value = set0(&ts->exc_value) );
630+
XINC( save_exc_type = set0(&ts->exc_type) );
625631
XINC( save_exc_traceback = set0(&ts->exc_traceback) );
626632
#endif
627633

@@ -832,20 +838,24 @@ static int pybigfile_loadblk(BigFile *file, blk_t blk, void *buf)
832838
WARN("I will crash"); // TODO dump which generator is still running
833839
BUG();
834840
}
835-
exc_type = ts->exc_state.exc_type;
836841
exc_value = ts->exc_state.exc_value;
842+
# if !BIGFILE_PYTS_EXC_INFO_ONLY_EXC_VALUE
843+
exc_type = ts->exc_state.exc_type;
837844
exc_traceback = ts->exc_state.exc_traceback;
845+
# endif
838846
#else
839-
exc_type = ts->exc_type;
840847
exc_value = ts->exc_value;
848+
exc_type = ts->exc_type;
841849
exc_traceback = ts->exc_traceback;
842850
#endif
843-
if (exc_type) {
851+
if (exc_value) {
844852
WARN("python thread-state found with handled but not cleared exception state");
845853
WARN("I will dump it and then crash");
846-
fprintf(stderr, "ts->exc_type:\t"); PyObject_Print(exc_type, stderr, 0);
847-
fprintf(stderr, "\nts->exc_value:\t"); PyObject_Print(exc_value, stderr, 0);
854+
fprintf(stderr, "ts->exc_value:\t"); PyObject_Print(exc_value, stderr, 0);
855+
#if !BIGFILE_PYTS_EXC_INFO_ONLY_EXC_VALUE
856+
fprintf(stderr, "\nts->exc_type:\t"); PyObject_Print(exc_type, stderr, 0);
848857
fprintf(stderr, "\nts->exc_traceback:\t"); PyObject_Print(exc_traceback, stderr, 0);
858+
#endif
849859
fprintf(stderr, "\n");
850860
PyErr_Display(exc_type, exc_value, exc_traceback);
851861
}
@@ -864,14 +874,16 @@ static int pybigfile_loadblk(BigFile *file, blk_t blk, void *buf)
864874
ts->curexc_traceback = save_curexc_traceback;
865875

866876
#if BIGFILE_USE_PYTS_EXC_INFO
867-
ts->exc_state.exc_type = save_exc_type;
868877
ts->exc_state.exc_value = save_exc_value;
878+
# if !BIGFILE_PYTS_EXC_INFO_ONLY_EXC_VALUE
879+
ts->exc_state.exc_type = save_exc_type;
869880
ts->exc_state.exc_traceback = save_exc_traceback;
881+
# endif
870882
ts->exc_info = save_exc_info;
871883
BUG_ON(ts->exc_state.previous_item != NULL);
872884
#else
873-
ts->exc_type = save_exc_type;
874885
ts->exc_value = save_exc_value;
886+
ts->exc_type = save_exc_type;
875887
ts->exc_traceback = save_exc_traceback;
876888
#endif
877889

@@ -1341,8 +1353,8 @@ XPyErr_SetFromErrno(void)
13411353
static void
13421354
XPyErr_FullClear(void)
13431355
{
1344-
PyObject *x_curexc_type, *x_curexc_value, *x_curexc_traceback;
1345-
PyObject *x_exc_type, *x_exc_value, *x_exc_traceback;
1356+
PyObject *x_curexc_value, *x_curexc_type, *x_curexc_traceback;
1357+
PyObject *x_exc_value, *x_exc_type = NULL, *x_exc_traceback = NULL;
13461358
PyObject *x_async_exc;
13471359
PyThreadState *ts;
13481360

@@ -1354,12 +1366,14 @@ XPyErr_FullClear(void)
13541366
#if BIGFILE_USE_PYTS_EXC_INFO
13551367
/* NOTE clearing top-level exc_state; if there is an active generator
13561368
* spawned - its exc state is preserved. */
1357-
x_exc_type = set0(&ts->exc_state.exc_type);
13581369
x_exc_value = set0(&ts->exc_state.exc_value);
1370+
# if !BIGFILE_PYTS_EXC_INFO_ONLY_EXC_VALUE
1371+
x_exc_type = set0(&ts->exc_state.exc_type);
13591372
x_exc_traceback = set0(&ts->exc_state.exc_traceback);
1373+
# endif
13601374
#else
1361-
x_exc_type = set0(&ts->exc_type);
13621375
x_exc_value = set0(&ts->exc_value);
1376+
x_exc_type = set0(&ts->exc_type);
13631377
x_exc_traceback = set0(&ts->exc_traceback);
13641378
#endif
13651379
x_async_exc = set0(&ts->async_exc);

0 commit comments

Comments
 (0)