12

If I do (e.g.)

 open("/snafu/fnord")

in Python (and the file does not exist), I get a traceback and the message

 IOError: [Errno 2] No such file or directory: '/snafu/fnord'

I would like to get the above string with Python's C API (i.e., a Python interpreter embedded in a C program). I need it as a string, not output to the console.

With PyErr_Fetch() I can get the type object of the exception and the value. For the above example, the value is a tuple:

 (2, 'No such file or directory', '/snafu/fnord')

Is there an easy way from the information I get from PyErr_Fetch() to the string the Python interpreter shows? (One that does not involve to construct such strings for each exception type yourself.)

Amro
  • 123,847
  • 25
  • 243
  • 454
ashcatch
  • 2,327
  • 1
  • 18
  • 29

1 Answers1

9

I think that Python exceptions are printed by running "str()" on the exception instance, which will return the formatted string you're interested in. You can get this from C by calling the PyObject_Str() method described here:

https://docs.python.org/c-api/object.html

Good luck!

Update: I'm a bit confused why the second element being returned to you by PyErr_Fetch() is a string. My guess is that you are receiving an "unnormalized exception" and need to call PyErr_NormalizeException() to turn that tuple into a "real" Exception that can format itself as a string like you want it to.

greatwolf
  • 20,287
  • 13
  • 71
  • 105
Brandon Rhodes
  • 83,755
  • 16
  • 106
  • 147
  • The second argument is a tuple and not a string. And I already call PyErr_NormalizeException(). But PyErr_Fetch() does not return an exception object, only the exception type. So I have to create the exception object myself, I guess? And I pass the second argument of PyErr_Fetch() to the constructor? – ashcatch Jun 16 '09 at 13:56
  • 1
    Oh, just checked my code and I did not call PyErr_NormalizeException() in all cases. Calling it, indeed turns the second argument into an exception object. And converting that one to a string with PyObject_Str() gets me the desired result. Thanks a lot. – ashcatch Jun 16 '09 at 14:00