]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.11] gh-106033: Get rid of new occurrences of PyDict_GetItem and Py… (#106040)
authorSerhiy Storchaka <storchaka@gmail.com>
Sat, 24 Jun 2023 23:41:02 +0000 (02:41 +0300)
committerGitHub <noreply@github.com>
Sat, 24 Jun 2023 23:41:02 +0000 (16:41 -0700)
[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)

Modules/_hashopenssl.c
Objects/exceptions.c
Python/pythonrun.c

index 4123c0c6907bc1cc8c37b01509a73c34d5b13376..57d64bd80c9727825a6c84cebd5c40e678681686 100644 (file)
@@ -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;
     }
 
index a95b75205b874917d1d4b296c958c26ab2bd893b..86cabbf3f17f7ac7e661c25abe369084436b50fa 100644 (file)
@@ -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);
index efa22b07256c82c87c9f84ae85fad702d8cc37f8..03e366a8d095dd829e50385232eb19cb6dafb989 100644 (file)
@@ -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;
         }