@@ -602,23 +602,64 @@ const char* pesapi_get_exception_as_string(pesapi_scope pscope, int with_stack)
602602 {
603603 return nullptr ;
604604 }
605- auto ex = scope->caught ->ex ;
606605 auto globals = PyModule_GetDict (PyImport_AddModule (" __main__" ));
607- PyDict_SetItem (globals, PyUnicode_FromString ( " __pesapi_last_exception " ), ex);
608- const char * ret;
606+
607+ const char * ret = nullptr ;
609608 if (with_stack)
610609 {
610+ #if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 12
611+ PyDict_SetItem (globals, PyUnicode_FromString (" __pesapi_last_exception" ), scope->caught ->value );
611612 PyRun_SimpleString (
612613 " import traceback\n "
613- " try :\n "
614- " raise __pesapi_last_exception\n "
615- " except Exception as e :\n "
616- " __pesapi_last_exception_str = ''.join(traceback.format_exception (type(e ), e, e.__traceback__ ))\n " );
614+ " if __pesapi_last_exception.__traceback__ is not None :\n "
615+ " __pesapi_last_exception_str = ''.join(traceback.format_exception(type( __pesapi_last_exception), __pesapi_last_exception, __pesapi_last_exception.__traceback__)) \n "
616+ " else :\n "
617+ " __pesapi_last_exception_str = ''.join(traceback.format_exception_only (type(__pesapi_last_exception ), __pesapi_last_exception ))\n " );
617618 ret = PyUnicode_AsUTF8 (PyDict_GetItem (globals, PyUnicode_FromString (" __pesapi_last_exception_str" )));
619+ #else
620+ auto tracebackModule = PyImport_ImportModule (" traceback" );
621+ auto traceback = scope->caught ->traceback ;
622+ auto type = scope->caught ->type ;
623+ auto value = scope->caught ->value ;
624+ if (traceback)
625+ {
626+ if (PyObject* formatExceptionFunc = PyObject_GetAttrString (tracebackModule, " format_exception" );
627+ formatExceptionFunc && PyCallable_Check (formatExceptionFunc))
628+ {
629+ if (PyObject* formattedList = PyObject_CallFunctionObjArgs (formatExceptionFunc, type, value, traceback, nullptr ))
630+ {
631+ if (PyObject* formattedStr = PyUnicode_Join (PyUnicode_FromString (" " ), formattedList))
632+ {
633+ ret = strdup (PyUnicode_AsUTF8 (formattedStr));
634+ Py_DECREF (formattedStr);
635+ }
636+ Py_DECREF (formattedList);
637+ }
638+ Py_DECREF (formatExceptionFunc);
639+ }
640+ }
641+ else
642+ {
643+ if (PyObject* formatExceptionOnlyFunc = PyObject_GetAttrString (tracebackModule, " format_exception_only" );
644+ formatExceptionOnlyFunc && PyCallable_Check (formatExceptionOnlyFunc))
645+ {
646+ if (PyObject* formattedList = PyObject_CallFunctionObjArgs (formatExceptionOnlyFunc, type, value, nullptr ))
647+ {
648+ if (PyObject* formattedStr = PyUnicode_Join (PyUnicode_FromString (" " ), formattedList))
649+ {
650+ ret = strdup (PyUnicode_AsUTF8 (formattedStr));
651+ Py_DECREF (formattedStr);
652+ }
653+ Py_DECREF (formattedList);
654+ }
655+ Py_DECREF (formatExceptionOnlyFunc);
656+ }
657+ }
658+ #endif
618659 }
619660 else
620661 {
621- ret = PyUnicode_AsUTF8 (PyObject_Str (ex ));
662+ ret = PyUnicode_AsUTF8 (PyObject_Str (scope-> caught -> value ));
622663 }
623664 PyDict_DelItemString (globals, " __pesapi_last_exception" );
624665 return ret;
@@ -780,16 +821,13 @@ pesapi_value pesapi_call_function(
780821 else
781822 {
782823 auto scope = (pesapi_scope__*)mapper->getCurrentScope ();
783- #if PY_VERSION_HEX >= 0x030B0000
824+ #if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 12
784825 scope->setCaughtException (PyErr_GetRaisedException ());
785826#else
786827 {
787- PyObject *type = nullptr , *value = nullptr , *tb = nullptr ;
788- PyErr_Fetch (&type, &value, &tb);
789- PyObject *exc = value ? value : type;
790- if (exc) Py_XINCREF (exc);
791- PyErr_Restore (type, value, tb);
792- scope->setCaughtException (exc);
828+ PyObject *type = nullptr , *value = nullptr , *traceback = nullptr ;
829+ PyErr_Fetch (&type, &value, &traceback);
830+ scope->setCaughtException (type, value, traceback);
793831 }
794832#endif
795833 return nullptr ;
@@ -816,16 +854,13 @@ pesapi_value pesapi_eval(pesapi_env env, const uint8_t* code, size_t code_size,
816854 }
817855 }
818856 auto scope = (pesapi_scope__*)mapper->getCurrentScope ();
819- #if PY_VERSION_HEX >= 0x030B0000
857+ #if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 12
820858 scope->setCaughtException (PyErr_GetRaisedException ());
821859#else
822860 {
823- PyObject *type = nullptr , *value = nullptr , *tb = nullptr ;
824- PyErr_Fetch (&type, &value, &tb);
825- PyObject *exc = value ? value : type;
826- if (exc) Py_XINCREF (exc);
827- PyErr_Restore (type, value, tb);
828- scope->setCaughtException (exc);
861+ PyObject *type = nullptr , *value = nullptr , *traceback = nullptr ;
862+ PyErr_Fetch (&type, &value, &traceback);
863+ scope->setCaughtException (type, value, traceback);
829864 }
830865#endif
831866 return nullptr ;
0 commit comments