Skip to content

Commit 1d33d53

Browse files
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.
1 parent 41ad4df commit 1d33d53

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
@@ -1508,11 +1508,14 @@ type_set_annotations(PyTypeObject *type, PyObject *value, void *context)
15081508
static PyObject *
15091509
type_get_type_params(PyTypeObject *type, void *context)
15101510
{
1511-
PyObject *params = PyDict_GetItem(lookup_tp_dict(type), &_Py_ID(__type_params__));
1511+
PyObject *params = PyDict_GetItemWithError(lookup_tp_dict(type), &_Py_ID(__type_params__));
15121512

15131513
if (params) {
15141514
return Py_NewRef(params);
15151515
}
1516+
if (PyErr_Occurred()) {
1517+
return NULL;
1518+
}
15161519

15171520
return PyTuple_New(0);
15181521
}

Python/pythonrun.c

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

1137-
if (!PyObject_HasAttr(value, &_Py_ID(__notes__))) {
1138-
return 0;
1139-
}
1140-
PyObject *notes = PyObject_GetAttr(value, &_Py_ID(__notes__));
1141-
if (notes == NULL) {
1142-
return -1;
1137+
PyObject *notes;
1138+
int res = _PyObject_LookupAttr(value, &_Py_ID(__notes__), &notes);
1139+
if (res <= 0) {
1140+
return res;
11431141
}
11441142
if (!PySequence_Check(notes) || PyUnicode_Check(notes) || PyBytes_Check(notes)) {
1145-
int res = 0;
1143+
res = 0;
11461144
if (write_indented_margin(ctx, f) < 0) {
11471145
res = -1;
11481146
}

0 commit comments

Comments
 (0)