Boost.Python在打印回溯时抛出异常

时间:2016-06-19 06:08:45

标签: python c++ python-3.x boost traceback

环境:Python 3.5和Boost 1.61。

我有一个打印python traceback的函数。它依赖于以下机制:

traceback.format_exception(exType, value, traceBack);

这是函数本身:

std::string pythonTraceBack()
{
    using namespace boost::python;
    PyObject* exType;
    PyObject* value;
    PyObject* traceBack;
    PyErr_Fetch(&exType, &value, &traceBack);
    object oExType(handle<>(borrowed(exType)));
    object oValue(handle<>(borrowed(value)));
    object oTraceBack(handle<>(borrowed(traceBack)));
    // 1.
    object lines = import("traceback").attr("format_exception")(oExType, oValue, oTraceBack);
    std::string result;
    for (int i = 0; i < len(lines); ++i)
        result += extract<std::string>(lines[i])();
    // 2.
    PyErr_Restore(exType, value, traceBack);
    return result;
}
  1. 这条线似乎导致了这个问题。用
  2. 替换它
    object lines = import("traceback").attr("format_exc")();
    

    似乎解决了问题,但输出不是追溯。

    1. 我试着评论这一行并没有改变。
    2. 我也尝试将oExType, oValue, oTraceBack替换为相应的原始对象exType, value, traceBack,但这会在编译期间导致转换错误。

      最小,完整,可验证的例子:

      #include <iostream>
      #include <Python.h>
      #include <boost/python.hpp>
      
      std::string pythonTraceBack() { /* ... */ }
      
      int main()
      {
          using namespace boost::python;
          Py_Initialize();
      
          try
          {
              object main_module = import("__main__");
              object main_namespace = main_module.attr("__dict__");
      
              object ignored = exec("print(1/0)", main_namespace);
          }
          catch (error_already_set const& e)
          {
              std::string error = pythonTraceBack();
              std::cout << "Traceback: " << std::endl << error;
          }
      
          // Py_Finalize();
          return 0;
      }
      

0 个答案:

没有答案