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).
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to