[Python-Dev] PyErr_ Fetch | Restore & friends

Ethan Furman ethan at stoneleaf.us
Sat Mar 29 18:05:51 CET 2014


I'm working on issue 1615 [1] and came up with this tidbit, which works [2], but not well enough:

  slot_tp_getattr_hook(PyObject *self, PyObject *name)
  {
      ...
+    PyObject *error_type, *error_value, *error_traceback;
      ...
+    /* if an AttributeError is set, save it and call getattr; if getattr
+       sets an AttributeError, discard it and return the original
+       AttributeError */
      if (res == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) {
+        PyErr_Fetch(&error_type, &error_value, &error_traceback);
          res = call_attribute(self, getattr, name);
+        if (res == NULL && PyErr_ExceptionMatches(PyExc_AttributeError))
+            PyErr_Restore(error_type, error_value, error_traceback);
      }

So I tried adding in a second call to PyErr_Fetch and adding the original error as context, like so:

     if (res == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) {
         PyErr_Fetch(&ctx_error_type, &ctx_error_value, &ctx_error_traceback);
         res = call_attribute(self, getattr, name);
         if (res == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) {
             PyErr_Fetch(&error_type, &error_value, &error_traceback);
             PyException_SetContext(error_value, ctx_error_value);
             PyErr_Restore(error_type, error_value, error_traceback);
         } else {
             Py_DECREF(ctx_error_value);
         }
         Py_DECREF(ctx_error_type);
         Py_DECREF(ctx_error_traceback);
     }

This bit of code won't even finish compiling.  I am not sure if my understanding of references (and how these functions 
create/consume them) or my understanding of when and where to call PyErr_Fetch|Restore or PyException_SetContext is at 
fault, but I would greatly appreciate somebody correcting my understanding.  :)

--
~Ethan~

[1] http://http://bugs.python.org/issue1615
[2] works as in everything compiles, but the resulting behavior introduces a new bug (the message of a 'raise 
AttributeError' in a __getattr__ is ignored).


More information about the Python-Dev mailing list