summaryrefslogtreecommitdiff
path: root/Objects/object.c
diff options
context:
space:
mode:
Diffstat (limited to 'Objects/object.c')
-rw-r--r--Objects/object.c34
1 files changed, 22 insertions, 12 deletions
diff --git a/Objects/object.c b/Objects/object.c
index ff816cd5b9..47c352e3d6 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -890,19 +890,29 @@ set_attribute_error_context(PyObject* v, PyObject* name)
assert(PyErr_Occurred());
_Py_IDENTIFIER(name);
_Py_IDENTIFIER(obj);
- // Intercept AttributeError exceptions and augment them to offer
- // suggestions later.
- if (PyErr_ExceptionMatches(PyExc_AttributeError)){
- PyObject *type, *value, *traceback;
- PyErr_Fetch(&type, &value, &traceback);
- PyErr_NormalizeException(&type, &value, &traceback);
- if (PyErr_GivenExceptionMatches(value, PyExc_AttributeError) &&
- (_PyObject_SetAttrId(value, &PyId_name, name) ||
- _PyObject_SetAttrId(value, &PyId_obj, v))) {
- return 1;
- }
- PyErr_Restore(type, value, traceback);
+ if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
+ return 0;
+ }
+ // Intercept AttributeError exceptions and augment them to offer suggestions later.
+ PyObject *type, *value, *traceback;
+ PyErr_Fetch(&type, &value, &traceback);
+ PyErr_NormalizeException(&type, &value, &traceback);
+ // Check if the normalized exception is indeed an AttributeError
+ if (!PyErr_GivenExceptionMatches(value, PyExc_AttributeError)) {
+ goto restore;
+ }
+ PyAttributeErrorObject* the_exc = (PyAttributeErrorObject*) value;
+ // Check if this exception was already augmented
+ if (the_exc->name || the_exc->obj) {
+ goto restore;
+ }
+ // Augment the exception with the name and object
+ if (_PyObject_SetAttrId(value, &PyId_name, name) ||
+ _PyObject_SetAttrId(value, &PyId_obj, v)) {
+ return 1;
}
+restore:
+ PyErr_Restore(type, value, traceback);
return 0;
}