Skip to content

Commit 9cd3664

Browse files
[3.12] gh-106033: Get rid of new occurrences of PyDict_GetItem and Py… (#106041)
[3.12] 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 1d33d53)
1 parent 746c0f3 commit 9cd3664

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)