[C++-sig] Displaying PyErr_Print() error

Benjamin Collar collar at gamic.com
Thu Nov 27 15:39:07 CET 2003


Greetings

The solution I found suggests making an object in python that has a function, 
'write(self, stuff)' . Anything written is kept in an instance string. 
Instantiate that class in the interpreter and replace sys.stderr with it. In 
your catch, query that object for its string. 

I'm not sure if this example is correct / valid / safe / anything else. 
However, it works for me. If anyone has any suggestions, fire away! (I'm 
guessing the first suggestion will be, 'why not make the OutputCatcher an 
exposed c++ class' Good suggestion, that; the python version was simply 
faster for me to implement.)

try
{
....
          python::handle<> rxa(
            PyRun_String("class OutputCatcher:\n"
              "\tdef __init__(self):\n"
              "\t\tself.data=''\n"
              "\tdef write(self, stuff):\n"
              "\t\tself.data = self.data + stuff\n\n"
              "import sys\n"
              "_catcher = OutputCatcher()\n"
              "sys.stderr = _catcher\n",
              Py_file_input, m_main_namespace.ptr(), m_main_namespace.ptr()));
....
}
catch {
  // this prints the exception to the catcher object.
  PyErr_Print();
  // get the string data out of this object.
  QString extractedError="cannot print exception";
  python::object catcher(m_main_namespace["_catcher"]);
  python::object cstr(catcher.attr("data"));
  if (char *sstr = PyString_AsString(cstr.ptr()))
    extractedError=sstr;
}

Ben

On Thursday 27 November 2003 13:07, Paul Grenyer wrote:
> Hi
>
> I originally asked this question some weeks ago, but didn't receive a
> reply. I've seen from googling that other people have had this problem,
> but I haven't seen a solution yet.
>
> I've intergrated boost.python into a COM object and therefore there is
> no std::cerr console to display the error message generated by
> PyErr_Print() after an exception is thrown.
>
> I've tried redirecting std::cerr to a stream:
>
> catch( const error_already_set& )
> {
>     std::stringstream str;
>     std::streambuf* streamBuffer = std::cerr.rdbuf( str.rdbuf() );
>
>     PyErr_Print();
>     std::cerr << python << std::endl;
>
>     std::cerr.rdbuf( streamBuffer );
>     throw BadPython( str.str(), __FILE__, __LINE__ );
> }
>
> The contents of "python", a string holding the python code that
> generated the exception, is correctly send to "str", but the exception
> message isn't.
>
> Am I doing something wrong? Is there another way to get the error
> generated by PyErr_Print() in a string?
>
> Regards
> Paul
>
> Please note the change of email address!
>
> Paul Grenyer
> Email: paul at paulgrenyer.co.uk
> Web: www.paulgrenyer.co.uk
>
>
>
> _______________________________________________
> C++-sig mailing list
> C++-sig at python.org
> http://mail.python.org/mailman/listinfo/c++-sig

-- 
----------------------------------------

(o__      Benjamin Collar
//\       GAMIC mbH  ++49 (0)241 889 110
V_/_      Developer/System Administrator 

To know recursion, you must first know recursion





More information about the Cplusplus-sig mailing list