- Notifications
You must be signed in to change notification settings - Fork 337
/
Copy pathpython_utils.cpp
84 lines (73 loc) · 2.68 KB
/
python_utils.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
/*
* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0,
* as published by the Free Software Foundation.
*
* This program is designed to work with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms, as
* designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an additional
* permission to link the program and your derivative works with the
* separately licensed software that they have either included with
* the program or referenced in the documentation.
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU General Public License, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#definePY_SSIZE_T_CLEAN
#if defined(_MSC_VER)
#include<Python/Python.h>
#else
#include<Python.h>
#endif
#include<frameobject.h>
#include"base/python_utils.h"
#include"base/string_utilities.h"
std::string format_python_traceback(PyObject *tb) {
PyTracebackObject *trace = (PyTracebackObject *)tb;
std::string stack;
stack = "Traceback:\n";
while (trace && trace->tb_frame) {
PyFrameObject *frame = (PyFrameObject *)trace->tb_frame;
PyCodeObject *code = PyFrame_GetCode(frame);
if(code) {
stack += base::strfmt(" File \"%s\", line %i, in %s\n", PyUnicode_AsUTF8(code->co_filename),
trace->tb_lineno, PyUnicode_AsUTF8(code->co_name));
PyObject *error = PyErr_ProgramText(PyUnicode_AsUTF8(code->co_filename), trace->tb_lineno);
if (error) {
stack += base::strfmt(" %s", PyUnicode_AsUTF8(error));
Py_DECREF(error);
}
Py_DECREF(code);
}
trace = trace->tb_next;
}
return stack;
}
std::string base::format_python_exception(std::string &summary) {
std::string reason, stack;
PyObject *exc, *val, *tb;
PyErr_Fetch(&exc, &val, &tb);
PyErr_NormalizeException(&exc, &val, &tb);
if (val) {
PyObject *tmp = PyObject_Str(val);
if (tmp) {
reason = PyUnicode_AsUTF8(tmp);
Py_DECREF(tmp);
}
}
if (tb)
stack = format_python_traceback(tb);
else
stack = "No stack information. ";
PyErr_Restore(exc, val, tb);
summary = reason;
return stack + reason + "\n";
}