私は最近、Python 3.4.3からPython 3.5.2にPythonを埋め込んだC++プロジェクトをアップグレードしました(これは32または64ビットとしてビルドされます)両方のバージョンで同じ動作をします)。 Pythonコードによって呼び出されるいくつかのC++のコードでそれを引き上げその後C/C++ Python例外のトレースバックが生成されていません
static PyObject* MyException_type_obj = 0;
void setup(PyObject* module){
MyException_type_obj = PyErr_NewException("my_module.MyException", NULL, NULL);
PyObject* dict = PyModule_GetDict(module);
PyDict_SetItemString(dict, "MyException", MyException_type_obj);
}
:
私は自分の例外を作成してい
static PyObject* RaiseIt(PyObject* self, PyObject* args)
{
PyErr_Format(Forever_Exception_type_obj, "Exit Requested");
return 0;
}
これまでのところ、とても良いです。私がPythonでそれを捕まえれば、すべてが問題ありません。
try:
my_module.raise_it()
except my_module.MyException:
import sys, traceback
exc_type, exc_value, exc_tb = sys.exc_info()
print(traceback.format_exception(exc_type, exc_value, exc_tb)
正しいtracbackをコマンドラインに表示します。しかし
、私はPyErr_Fetch
を使用するC++/Pythonで同じようなことをやろう:
std::string get_traceback(){
PyObject* type;
PyObject* value;
PyObject* traceback;
PyErr_Fetch(&type, &value, &traceback);
std::string fcn = "";
fcn += "def get_pretty_traceback(exc_type, exc_value, exc_tb):\n";
fcn += " import sys, traceback\n";
fcn += " lines = []\n";
fcn += " lines = traceback.format_exception(exc_type, exc_value, exc_tb)\n";
fcn += " output = '\\n'.join(lines)\n";
fcn += " return output\n";
PyRun_SimpleString(fcn.c_str());
PyObject* mod = PyImport_ImportModule("__main__");
PyObject* method = PyObject_GetAttrString(mod, "get_pretty_traceback");
PyObject* outStr = PyObject_CallObject(method, Py_BuildValue("OOO", type, value, traceback));
std::string pretty = PyBytes_AsString(PyUnicode_AsASCIIString(outStr));
Py_DECREF(method);
Py_DECREF(outStr);
return pretty;
}
それが故障し、私がnull outStr
を取得します。これはどちらか(マイナー文字列に関連した変化で)のpython 2.7で発生しません、余談として
'str' object has no attribute '__cause__'
:
取得いくつかの追加の詳細
fcn += " lines = []\n";
fcn += " try:\n";
fcn += " lines = traceback.format_exception(exc_type, exc_value, exc_tb)\n";
fcn += " except Exception as e:\n";
fcn += " print('Exception while rendering a python exception for C')\n";
fcn += " print(e)\n";
fcn += " output = '\\n'.join(lines)\n";
は私に不可解なエラーメッセージを表示します。それはPython 3.5で私にとって唯一のものです。
この同じC++のget_traceback()関数は、Pythonで開始された例外(C++の例外ではない)で正常に動作します。