Skip to content

Commit 1a53128

Browse files
committed
python 修复小于 3.12 版本下的异常处理 并精简异常信息
1 parent 1b62eb9 commit 1a53128

File tree

3 files changed

+60
-25
lines changed

3 files changed

+60
-25
lines changed

unity/native/papi-python/include/PapiData.h

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,25 @@ struct pesapi_value_ref__ : pesapi_env_ref__
5858

5959
struct caught_exception_info
6060
{
61-
PyObject* ex;
61+
#if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 12
62+
PyObject* value;
63+
#else
64+
PyObject* type;
65+
PyObject* value;
66+
PyObject* traceback;
67+
#endif
68+
~caught_exception_info()
69+
{
70+
#if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 12
71+
// From PyErr_GetRaisedException
72+
Py_XDECREF(value);
73+
#else
74+
// From PyErr_Fetch
75+
Py_XDECREF(type);
76+
Py_XDECREF(value);
77+
Py_XDECREF(traceback);
78+
#endif
79+
}
6280
};
6381

6482
struct pesapi_scope__;
@@ -110,20 +128,34 @@ struct pesapi_scope__
110128
return ret;
111129
}
112130

131+
#if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 12
132+
// From PyErr_GetRaisedException
113133
void setCaughtException(PyObject* ex)
114134
{
115135
if (caught == nullptr)
116136
{
117137
caught = (caught_exception_info*) PyMem_Malloc(sizeof(caught_exception_info));
118138
}
119-
caught->ex = ex;
139+
caught->value = ex;
140+
}
141+
#else
142+
// From PyErr_Fetch
143+
void setCaughtException(PyObject * type, PyObject * value, PyObject * traceback)
144+
{
145+
if (caught == nullptr)
146+
{
147+
caught = (caught_exception_info*) PyMem_Malloc(sizeof(caught_exception_info));
148+
}
149+
caught->type = type;
150+
caught->value = value;
151+
caught->traceback = traceback;
120152
}
153+
#endif
121154

122155
~pesapi_scope__()
123156
{
124157
if (caught)
125158
{
126-
Py_XDECREF(caught->ex);
127159
caught->~caught_exception_info();
128160
PyMem_Free(caught);
129161
}

unity/native/papi-python/source/PapiPythonImpl.cpp

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -602,23 +602,32 @@ 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);
606+
607+
PyDict_SetItem(globals, PyUnicode_FromString("__pesapi_last_exception"), scope->caught->value);
608+
#if !(PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 12)
609+
PyDict_SetItem(globals, PyUnicode_FromString("__pesapi_last_exception"), scope->caught->value);
610+
PyDict_SetItem(globals, PyUnicode_FromString("__pesapi_last_exception_tp"), scope->caught->type);
611+
PyDict_SetItem(globals, PyUnicode_FromString("__pesapi_last_exception_tb"), scope->caught->traceback);
612+
#endif
613+
608614
const char* ret;
609615
if (with_stack)
610616
{
617+
#if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 12
611618
PyRun_SimpleString(
612619
"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");
620+
"__pesapi_last_exception_str = ''.join(traceback.format_exception(type(__pesapi_last_exception), __pesapi_last_exception, __pesapi_last_exception.__traceback__))\n");
621+
#else
622+
PyRun_SimpleString(
623+
"import traceback\n"
624+
"__pesapi_last_exception_str = ''.join(traceback.format_exception(__pesapi_last_exception_tp, __pesapi_last_exception, __pesapi_last_exception_tb))\n");
625+
#endif
617626
ret = PyUnicode_AsUTF8(PyDict_GetItem(globals, PyUnicode_FromString("__pesapi_last_exception_str")));
618627
}
619628
else
620629
{
621-
ret = PyUnicode_AsUTF8(PyObject_Str(ex));
630+
ret = PyUnicode_AsUTF8(PyObject_Str(scope->caught->value));
622631
}
623632
PyDict_DelItemString(globals, "__pesapi_last_exception");
624633
return ret;
@@ -780,16 +789,13 @@ pesapi_value pesapi_call_function(
780789
else
781790
{
782791
auto scope = (pesapi_scope__*)mapper->getCurrentScope();
783-
#if PY_VERSION_HEX >= 0x030B0000
792+
#if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 12
784793
scope->setCaughtException(PyErr_GetRaisedException());
785794
#else
786795
{
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);
796+
PyObject *type = nullptr, *value = nullptr, *traceback = nullptr;
797+
PyErr_Fetch(&type, &value, &traceback);
798+
scope->setCaughtException(type, value, traceback);
793799
}
794800
#endif
795801
return nullptr;
@@ -816,16 +822,13 @@ pesapi_value pesapi_eval(pesapi_env env, const uint8_t* code, size_t code_size,
816822
}
817823
}
818824
auto scope = (pesapi_scope__*)mapper->getCurrentScope();
819-
#if PY_VERSION_HEX >= 0x030B0000
825+
#if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 12
820826
scope->setCaughtException(PyErr_GetRaisedException());
821827
#else
822828
{
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);
829+
PyObject *type = nullptr, *value = nullptr, *traceback = nullptr;
830+
PyErr_Fetch(&type, &value, &traceback);
831+
scope->setCaughtException(type, value, traceback);
829832
}
830833
#endif
831834
return nullptr;

unity/native/papi-python/test/papi_py_base_test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ TEST_F(PApiBaseTest, EvalJavaScriptEx)
427427

428428
EXPECT_STREQ("abc", apis->get_exception_as_string(scope, false));
429429
EXPECT_STREQ(
430-
"Traceback (most recent call last):\n File \"<string>\", line 3, in <module>\n File \"test.py\", line 1, in <module>\n "
430+
"Traceback (most recent call last):\n File \"test.py\", line 1, in <module>\n "
431431
"File \"test.py\", line 1, in <lambda>\n File \"test.py\", line 1, in <genexpr>\nException: abc\n",
432432
apis->get_exception_as_string(scope, true));
433433
}

0 commit comments

Comments
 (0)