From 4dc9f4893084f7c3acf78a0384620cd44f604a0d Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 23 Aug 2023 22:59:00 +0200 Subject: [PATCH] gh-108308: Replace _PyDict_GetItemStringWithError() (#108372) Replace _PyDict_GetItemStringWithError() calls with PyDict_GetItemStringRef() which returns a strong reference to the item. Co-authored-by: Serhiy Storchaka --- Objects/structseq.c | 25 ++++++++++--------------- Python/codecs.c | 12 +++++------- Python/import.c | 8 +++----- Python/pylifecycle.c | 26 ++++++++++++++------------ 4 files changed, 32 insertions(+), 39 deletions(-) diff --git a/Objects/structseq.c b/Objects/structseq.c index 95c4c15710d..6c07e636629 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -8,7 +8,6 @@ */ #include "Python.h" -#include "pycore_dict.h" // _PyDict_GetItemStringWithError() #include "pycore_tuple.h" // _PyTuple_FromArray() #include "pycore_object.h" // _PyObject_GC_TRACK() @@ -149,7 +148,6 @@ static PyObject * structseq_new_impl(PyTypeObject *type, PyObject *arg, PyObject *dict) /*[clinic end generated code: output=baa082e788b171da input=90532511101aa3fb]*/ { - PyObject *ob; PyStructSequence *res = NULL; Py_ssize_t len, min_len, max_len, i, n_unnamed_fields; @@ -219,21 +217,18 @@ structseq_new_impl(PyTypeObject *type, PyObject *arg, PyObject *dict) } Py_DECREF(arg); for (; i < max_len; ++i) { - if (dict == NULL) { - ob = Py_None; - } - else { - ob = _PyDict_GetItemStringWithError(dict, - type->tp_members[i-n_unnamed_fields].name); - if (ob == NULL) { - if (PyErr_Occurred()) { - Py_DECREF(res); - return NULL; - } - ob = Py_None; + PyObject *ob = NULL; + if (dict != NULL) { + const char *name = type->tp_members[i-n_unnamed_fields].name; + if (PyDict_GetItemStringRef(dict, name, &ob) < 0) { + Py_DECREF(res); + return NULL; } } - res->ob_item[i] = Py_NewRef(ob); + if (ob == NULL) { + ob = Py_NewRef(Py_None); + } + res->ob_item[i] = ob; } _PyObject_GC_TRACK(res); diff --git a/Python/codecs.c b/Python/codecs.c index 3c418512e3a..87ae896b8e7 100644 --- a/Python/codecs.c +++ b/Python/codecs.c @@ -10,7 +10,6 @@ Copyright (c) Corporation for National Research Initiatives. #include "Python.h" #include "pycore_call.h" // _PyObject_CallNoArgs() -#include "pycore_dict.h" // _PyDict_GetItemStringWithError() #include "pycore_interp.h" // PyInterpreterState.codec_search_path #include "pycore_pyerrors.h" // _PyErr_FormatNote() #include "pycore_pystate.h" // _PyInterpreterState_GET() @@ -618,20 +617,19 @@ int PyCodec_RegisterError(const char *name, PyObject *error) the error handling callback for strict encoding will be returned. */ PyObject *PyCodec_LookupError(const char *name) { - PyObject *handler = NULL; - PyInterpreterState *interp = _PyInterpreterState_GET(); if (interp->codec_search_path == NULL && _PyCodecRegistry_Init()) return NULL; if (name==NULL) name = "strict"; - handler = _PyDict_GetItemStringWithError(interp->codec_error_registry, name); - if (handler) { - Py_INCREF(handler); + PyObject *handler; + if (PyDict_GetItemStringRef(interp->codec_error_registry, name, &handler) < 0) { + return NULL; } - else if (!PyErr_Occurred()) { + if (handler == NULL) { PyErr_Format(PyExc_LookupError, "unknown error handler name '%.400s'", name); + return NULL; } return handler; } diff --git a/Python/import.c b/Python/import.c index 4abb2f6a06b..5681deb3c4f 100644 --- a/Python/import.c +++ b/Python/import.c @@ -1,7 +1,6 @@ /* Module definition and import implementation */ #include "Python.h" -#include "pycore_dict.h" // _PyDict_GetItemStringWithError() #include "pycore_hashtable.h" // _Py_hashtable_new_full() #include "pycore_import.h" // _PyImport_BootstrapImp() #include "pycore_initconfig.h" // _PyStatus_OK() @@ -2435,12 +2434,11 @@ int _PyImport_InitDefaultImportFunc(PyInterpreterState *interp) { // Get the __import__ function - PyObject *import_func = _PyDict_GetItemStringWithError(interp->builtins, - "__import__"); - if (import_func == NULL) { + PyObject *import_func; + if (PyDict_GetItemStringRef(interp->builtins, "__import__", &import_func) <= 0) { return -1; } - IMPORT_FUNC(interp) = Py_NewRef(import_func); + IMPORT_FUNC(interp) = import_func; return 0; } diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 8c321fbcfe4..18614264989 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1372,17 +1372,17 @@ finalize_modules_delete_special(PyThreadState *tstate, int verbose) if (verbose) { PySys_WriteStderr("# restore sys.%s\n", name); } - PyObject *value = _PyDict_GetItemStringWithError(interp->sysdict, - orig_name); + PyObject *value; + if (PyDict_GetItemStringRef(interp->sysdict, orig_name, &value) < 0) { + PyErr_WriteUnraisable(NULL); + } if (value == NULL) { - if (_PyErr_Occurred(tstate)) { - PyErr_WriteUnraisable(NULL); - } - value = Py_None; + value = Py_NewRef(Py_None); } if (PyDict_SetItemString(interp->sysdict, name, value) < 0) { PyErr_WriteUnraisable(NULL); } + Py_DECREF(value); } } @@ -2207,7 +2207,7 @@ _Py_IsInterpreterFinalizing(PyInterpreterState *interp) static PyStatus add_main_module(PyInterpreterState *interp) { - PyObject *m, *d, *loader, *ann_dict; + PyObject *m, *d, *ann_dict; m = PyImport_AddModule("__main__"); if (m == NULL) return _PyStatus_ERR("can't create __main__ module"); @@ -2239,11 +2239,13 @@ add_main_module(PyInterpreterState *interp) * will be set if __main__ gets further initialized later in the startup * process. */ - loader = _PyDict_GetItemStringWithError(d, "__loader__"); - if (loader == NULL || loader == Py_None) { - if (PyErr_Occurred()) { - return _PyStatus_ERR("Failed to test __main__.__loader__"); - } + PyObject *loader; + if (PyDict_GetItemStringRef(d, "__loader__", &loader) < 0) { + return _PyStatus_ERR("Failed to test __main__.__loader__"); + } + int has_loader = !(loader == NULL || loader == Py_None); + Py_XDECREF(loader); + if (!has_loader) { PyObject *loader = _PyImport_GetImportlibLoader(interp, "BuiltinImporter"); if (loader == NULL) {