[Python-checkins] [3.11] gh-106033: Get rid of new occurrences of PyDict_GetItem and Py… (#106040)

gpshead webhook-mailer at python.org
Sat Jun 24 19:41:05 EDT 2023


https://github.com/python/cpython/commit/dbe416b82b8a4ba69d263b915167ea1650ff2412
commit: dbe416b82b8a4ba69d263b915167ea1650ff2412
branch: 3.11
author: Serhiy Storchaka <storchaka at gmail.com>
committer: gpshead <greg at krypto.org>
date: 2023-06-24T16:41:02-07:00
summary:

[3.11] gh-106033: Get rid of new occurrences of PyDict_GetItem and Py… (#106040)

[3.11] gh-106033: Get rid of new occurrences of PyDict_GetItem and PyObject_HasAttr (GH-106034)

These functions are broken by design because they discard any exceptions raised
inside, including MemoryError and KeyboardInterrupt.  They should not be
used in new code..
(cherry picked from commit 1d33d5378058671bfabb6f4d4b5bfd4726973ff9)

files:
M Modules/_hashopenssl.c
M Objects/exceptions.c
M Python/pythonrun.c

diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c
index 4123c0c6907bc..57d64bd80c972 100644
--- a/Modules/_hashopenssl.c
+++ b/Modules/_hashopenssl.c
@@ -384,14 +384,15 @@ py_digest_by_digestmod(PyObject *module, PyObject *digestmod, enum Py_hash_type
     } else {
         _hashlibstate *state = get_hashlib_state(module);
         // borrowed ref
-        name_obj = PyDict_GetItem(state->constructs, digestmod);
+        name_obj = PyDict_GetItemWithError(state->constructs, digestmod);
     }
     if (name_obj == NULL) {
-        _hashlibstate *state = get_hashlib_state(module);
-        PyErr_Clear();
-        PyErr_Format(
-            state->unsupported_digestmod_error,
-            "Unsupported digestmod %R", digestmod);
+        if (!PyErr_Occurred()) {
+            _hashlibstate *state = get_hashlib_state(module);
+            PyErr_Format(
+                state->unsupported_digestmod_error,
+                "Unsupported digestmod %R", digestmod);
+        }
         return NULL;
     }
 
diff --git a/Objects/exceptions.c b/Objects/exceptions.c
index a95b75205b874..86cabbf3f17f7 100644
--- a/Objects/exceptions.c
+++ b/Objects/exceptions.c
@@ -210,22 +210,21 @@ BaseException_add_note(PyObject *self, PyObject *note)
         return NULL;
     }
 
-    if (!PyObject_HasAttr(self, &_Py_ID(__notes__))) {
-        PyObject *new_notes = PyList_New(0);
-        if (new_notes == NULL) {
+    PyObject *notes;
+    if (_PyObject_LookupAttr(self, &_Py_ID(__notes__), &notes) < 0) {
+        return NULL;
+    }
+    if (notes == NULL) {
+        notes = PyList_New(0);
+        if (notes == NULL) {
             return NULL;
         }
-        if (PyObject_SetAttr(self, &_Py_ID(__notes__), new_notes) < 0) {
-            Py_DECREF(new_notes);
+        if (PyObject_SetAttr(self, &_Py_ID(__notes__), notes) < 0) {
+            Py_DECREF(notes);
             return NULL;
         }
-        Py_DECREF(new_notes);
     }
-    PyObject *notes = PyObject_GetAttr(self, &_Py_ID(__notes__));
-    if (notes == NULL) {
-        return NULL;
-    }
-    if (!PyList_Check(notes)) {
+    else if (!PyList_Check(notes)) {
         Py_DECREF(notes);
         PyErr_SetString(PyExc_TypeError, "Cannot add note: __notes__ is not a list");
         return NULL;
@@ -943,11 +942,11 @@ exceptiongroup_subset(
     PyException_SetContext(eg, PyException_GetContext(orig));
     PyException_SetCause(eg, PyException_GetCause(orig));
 
-    if (PyObject_HasAttr(orig, &_Py_ID(__notes__))) {
-        PyObject *notes = PyObject_GetAttr(orig, &_Py_ID(__notes__));
-        if (notes == NULL) {
-            goto error;
-        }
+    PyObject *notes;
+    if (_PyObject_LookupAttr(orig, &_Py_ID(__notes__), &notes) < 0) {
+        goto error;
+    }
+    if (notes) {
         if (PySequence_Check(notes)) {
             /* Make a copy so the parts have independent notes lists. */
             PyObject *notes_copy = PySequence_List(notes);
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index efa22b07256c8..03e366a8d095d 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -1138,15 +1138,13 @@ print_exception_notes(struct exception_print_context *ctx, PyObject *value)
         return 0;
     }
 
-    if (!PyObject_HasAttr(value, &_Py_ID(__notes__))) {
-        return 0;
-    }
-    PyObject *notes = PyObject_GetAttr(value, &_Py_ID(__notes__));
-    if (notes == NULL) {
-        return -1;
+    PyObject *notes;
+    int res = _PyObject_LookupAttr(value, &_Py_ID(__notes__), &notes);
+    if (res <= 0) {
+        return res;
     }
     if (!PySequence_Check(notes)) {
-        int res = 0;
+        res = 0;
         if (write_indented_margin(ctx, f) < 0) {
             res = -1;
         }



More information about the Python-checkins mailing list