summaryrefslogtreecommitdiff
path: root/Objects/object.c
diff options
context:
space:
mode:
authorPablo Galindo Salgado <Pablogsal@gmail.com>2022-03-07 13:18:36 +0000
committerGitHub <noreply@github.com>2022-03-07 13:18:36 +0000
commit3594ebca2cacf5d9b5212d2c487fd017cd00e283 (patch)
tree3ce56e4a8c8ca51c54078f2b37efa469c34afea4 /Objects/object.c
parent8acbb93c0763fa53b5959fe05d86ba275c9e8a5b (diff)
downloadcpython-git-3594ebca2cacf5d9b5212d2c487fd017cd00e283.tar.gz
[3.10] bpo-46940: Don't override existing AttributeError suggestion information (GH-31710) (GH-31724)
When an exception is created in a nested call to PyObject_GetAttr, any external calls will override the context information of the AttributeError that we have already placed in the most internal call. This will cause the suggestions we create to nor work properly as the attribute name and object that we will be using are the incorrect ones. To avoid this, we need to check first if these attributes are already set and bail out if that's the case.. (cherry picked from commit 3b3be05a164da43f201e35b6dafbc840993a4d18) Co-authored-by: Pablo Galindo Salgado <Pablogsal@gmail.com>
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;
}