@@ -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)
13411353static void
13421354XPyErr_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