Skip to content

Commit 4224df2

Browse files
[3.12] pythongh-106033: Get rid of new occurrences of PyDict_GetItem and PyObject_HasAttr (pythonGH-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 1d33d53) Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
1 parent 7d6ee29 commit 4224df2

File tree

5 files changed

+32
-31
lines changed

5 files changed

+32
-31
lines changed

Modules/_hashopenssl.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -383,14 +383,15 @@ py_digest_by_digestmod(PyObject *module, PyObject *digestmod, enum Py_hash_type
383383
} else {
384384
_hashlibstate *state = get_hashlib_state(module);
385385
// borrowed ref
386-
name_obj = PyDict_GetItem(state->constructs, digestmod);
386+
name_obj = PyDict_GetItemWithError(state->constructs, digestmod);
387387
}
388388
if (name_obj == NULL) {
389-
_hashlibstate *state = get_hashlib_state(module);
390-
PyErr_Clear();
391-
PyErr_Format(
392-
state->unsupported_digestmod_error,
393-
"Unsupported digestmod %R", digestmod);
389+
if (!PyErr_Occurred()) {
390+
_hashlibstate *state = get_hashlib_state(module);
391+
PyErr_Format(
392+
state->unsupported_digestmod_error,
393+
"Unsupported digestmod %R", digestmod);
394+
}
394395
return NULL;
395396
}
396397

Modules/_testcapi/code.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ get_code_extra_index(PyInterpreterState* interp) {
99
PyObject *interp_dict = PyInterpreterState_GetDict(interp); // borrowed
1010
assert(interp_dict); // real users would handle missing dict... somehow
1111

12-
PyObject *index_obj = PyDict_GetItemString(interp_dict, key); // borrowed
12+
PyObject *index_obj = _PyDict_GetItemStringWithError(interp_dict, key); // borrowed
1313
Py_ssize_t index = 0;
1414
if (!index_obj) {
1515
if (PyErr_Occurred()) {

Objects/exceptions.c

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -207,22 +207,21 @@ BaseException_add_note(PyObject *self, PyObject *note)
207207
return NULL;
208208
}
209209

210-
if (!PyObject_HasAttr(self, &_Py_ID(__notes__))) {
211-
PyObject *new_notes = PyList_New(0);
212-
if (new_notes == NULL) {
210+
PyObject *notes;
211+
if (_PyObject_LookupAttr(self, &_Py_ID(__notes__), &notes) < 0) {
212+
return NULL;
213+
}
214+
if (notes == NULL) {
215+
notes = PyList_New(0);
216+
if (notes == NULL) {
213217
return NULL;
214218
}
215-
if (PyObject_SetAttr(self, &_Py_ID(__notes__), new_notes) < 0) {
216-
Py_DECREF(new_notes);
219+
if (PyObject_SetAttr(self, &_Py_ID(__notes__), notes) < 0) {
220+
Py_DECREF(notes);
217221
return NULL;
218222
}
219-
Py_DECREF(new_notes);
220223
}
221-
PyObject *notes = PyObject_GetAttr(self, &_Py_ID(__notes__));
222-
if (notes == NULL) {
223-
return NULL;
224-
}
225-
if (!PyList_Check(notes)) {
224+
else if (!PyList_Check(notes)) {
226225
Py_DECREF(notes);
227226
PyErr_SetString(PyExc_TypeError, "Cannot add note: __notes__ is not a list");
228227
return NULL;
@@ -941,11 +940,11 @@ exceptiongroup_subset(
941940
PyException_SetContext(eg, PyException_GetContext(orig));
942941
PyException_SetCause(eg, PyException_GetCause(orig));
943942

944-
if (PyObject_HasAttr(orig, &_Py_ID(__notes__))) {
945-
PyObject *notes = PyObject_GetAttr(orig, &_Py_ID(__notes__));
946-
if (notes == NULL) {
947-
goto error;
948-
}
943+
PyObject *notes;
944+
if (_PyObject_LookupAttr(orig, &_Py_ID(__notes__), &notes) < 0) {
945+
goto error;
946+
}
947+
if (notes) {
949948
if (PySequence_Check(notes)) {
950949
/* Make a copy so the parts have independent notes lists. */
951950
PyObject *notes_copy = PySequence_List(notes);

Objects/typeobject.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1507,11 +1507,14 @@ type_set_annotations(PyTypeObject *type, PyObject *value, void *context)
15071507
static PyObject *
15081508
type_get_type_params(PyTypeObject *type, void *context)
15091509
{
1510-
PyObject *params = PyDict_GetItem(lookup_tp_dict(type), &_Py_ID(__type_params__));
1510+
PyObject *params = PyDict_GetItemWithError(lookup_tp_dict(type), &_Py_ID(__type_params__));
15111511

15121512
if (params) {
15131513
return Py_NewRef(params);
15141514
}
1515+
if (PyErr_Occurred()) {
1516+
return NULL;
1517+
}
15151518

15161519
return PyTuple_New(0);
15171520
}

Python/pythonrun.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,15 +1100,13 @@ print_exception_notes(struct exception_print_context *ctx, PyObject *value)
11001100
return 0;
11011101
}
11021102

1103-
if (!PyObject_HasAttr(value, &_Py_ID(__notes__))) {
1104-
return 0;
1105-
}
1106-
PyObject *notes = PyObject_GetAttr(value, &_Py_ID(__notes__));
1107-
if (notes == NULL) {
1108-
return -1;
1103+
PyObject *notes;
1104+
int res = _PyObject_LookupAttr(value, &_Py_ID(__notes__), &notes);
1105+
if (res <= 0) {
1106+
return res;
11091107
}
11101108
if (!PySequence_Check(notes) || PyUnicode_Check(notes) || PyBytes_Check(notes)) {
1111-
int res = 0;
1109+
res = 0;
11121110
if (write_indented_margin(ctx, f) < 0) {
11131111
res = -1;
11141112
}

0 commit comments

Comments
 (0)