diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2023-09-17 11:23:31 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-09-17 11:23:31 (GMT) |
commit | add16f1a5e4013f97d33cc677dc008e8199f5b11 (patch) | |
tree | 2c187adbae2766f942e35780950a526dfe84ff48 /Modules | |
parent | e57ecf6bbc59f999d27b125ea51b042c24a07bd9 (diff) | |
download | cpython-add16f1a5e4013f97d33cc677dc008e8199f5b11.zip cpython-add16f1a5e4013f97d33cc677dc008e8199f5b11.tar.gz cpython-add16f1a5e4013f97d33cc677dc008e8199f5b11.tar.bz2 |
gh-108511: Add C API functions which do not silently ignore errors (GH-109025)
Add the following functions:
* PyObject_HasAttrWithError()
* PyObject_HasAttrStringWithError()
* PyMapping_HasKeyWithError()
* PyMapping_HasKeyStringWithError()
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/_ctypes/stgdict.c | 6 | ||||
-rw-r--r-- | Modules/_elementtree.c | 3 | ||||
-rw-r--r-- | Modules/_io/iobase.c | 6 | ||||
-rw-r--r-- | Modules/_io/textio.c | 3 | ||||
-rw-r--r-- | Modules/_pickle.c | 7 | ||||
-rw-r--r-- | Modules/_testcapi/abstract.c | 54 | ||||
-rw-r--r-- | Modules/_xxinterpchannelsmodule.c | 2 | ||||
-rw-r--r-- | Modules/_xxsubinterpretersmodule.c | 2 |
8 files changed, 65 insertions, 18 deletions
diff --git a/Modules/_ctypes/stgdict.c b/Modules/_ctypes/stgdict.c index 9b0ca73..6fbcf77 100644 --- a/Modules/_ctypes/stgdict.c +++ b/Modules/_ctypes/stgdict.c @@ -386,11 +386,11 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct if (fields == NULL) return 0; - if (PyObject_GetOptionalAttr(type, &_Py_ID(_swappedbytes_), &tmp) < 0) { + int rc = PyObject_HasAttrWithError(type, &_Py_ID(_swappedbytes_)); + if (rc < 0) { return -1; } - if (tmp) { - Py_DECREF(tmp); + if (rc) { big_endian = !PY_BIG_ENDIAN; } else { diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index 8cb57e6..f9d5793 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -3532,12 +3532,11 @@ expat_start_doctype_handler(XMLParserObject *self, sysid_obj, NULL); Py_XDECREF(res); } - else if (PyObject_GetOptionalAttr((PyObject *)self, st->str_doctype, &res) > 0) { + else if (PyObject_HasAttrWithError((PyObject *)self, st->str_doctype) > 0) { (void)PyErr_WarnEx(PyExc_RuntimeWarning, "The doctype() method of XMLParser is ignored. " "Define doctype() method on the TreeBuilder target.", 1); - Py_DECREF(res); } Py_DECREF(doctype_name_obj); diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c index 34fcd70..78f0f94 100644 --- a/Modules/_io/iobase.c +++ b/Modules/_io/iobase.c @@ -148,13 +148,9 @@ _io__IOBase_truncate_impl(PyObject *self, PyTypeObject *cls, static int iobase_is_closed(PyObject *self) { - PyObject *res; - int ret; /* This gets the derived attribute, which is *not* __IOBase_closed in most cases! */ - ret = PyObject_GetOptionalAttr(self, &_Py_ID(__IOBase_closed), &res); - Py_XDECREF(res); - return ret; + return PyObject_HasAttrWithError(self, &_Py_ID(__IOBase_closed)); } /* Flush and close methods */ diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index 0a727a6..91b677b 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -1223,11 +1223,10 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer, goto error; self->seekable = self->telling = r; - r = PyObject_GetOptionalAttr(buffer, &_Py_ID(read1), &res); + r = PyObject_HasAttrWithError(buffer, &_Py_ID(read1)); if (r < 0) { goto error; } - Py_XDECREF(res); self->has_read1 = r; self->encoding_start_of_stream = 0; diff --git a/Modules/_pickle.c b/Modules/_pickle.c index b975248..a3cf346 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -5799,14 +5799,13 @@ instantiate(PyObject *cls, PyObject *args) into a newly created tuple. */ assert(PyTuple_Check(args)); if (!PyTuple_GET_SIZE(args) && PyType_Check(cls)) { - PyObject *func; - if (PyObject_GetOptionalAttr(cls, &_Py_ID(__getinitargs__), &func) < 0) { + int rc = PyObject_HasAttrWithError(cls, &_Py_ID(__getinitargs__)); + if (rc < 0) { return NULL; } - if (func == NULL) { + if (!rc) { return PyObject_CallMethodOneArg(cls, &_Py_ID(__new__), cls); } - Py_DECREF(func); } return PyObject_CallObject(cls, args); } diff --git a/Modules/_testcapi/abstract.c b/Modules/_testcapi/abstract.c index bde0d28..81a3dea 100644 --- a/Modules/_testcapi/abstract.c +++ b/Modules/_testcapi/abstract.c @@ -106,6 +106,31 @@ object_hasattrstring(PyObject *self, PyObject *args) } static PyObject * +object_hasattrwitherror(PyObject *self, PyObject *args) +{ + PyObject *obj, *attr_name; + if (!PyArg_ParseTuple(args, "OO", &obj, &attr_name)) { + return NULL; + } + NULLABLE(obj); + NULLABLE(attr_name); + RETURN_INT(PyObject_HasAttrWithError(obj, attr_name)); +} + +static PyObject * +object_hasattrstringwitherror(PyObject *self, PyObject *args) +{ + PyObject *obj; + const char *attr_name; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "Oz#", &obj, &attr_name, &size)) { + return NULL; + } + NULLABLE(obj); + RETURN_INT(PyObject_HasAttrStringWithError(obj, attr_name)); +} + +static PyObject * object_setattr(PyObject *self, PyObject *args) { PyObject *obj, *attr_name, *value; @@ -281,6 +306,31 @@ mapping_haskeystring(PyObject *self, PyObject *args) } static PyObject * +mapping_haskeywitherror(PyObject *self, PyObject *args) +{ + PyObject *mapping, *key; + if (!PyArg_ParseTuple(args, "OO", &mapping, &key)) { + return NULL; + } + NULLABLE(mapping); + NULLABLE(key); + RETURN_INT(PyMapping_HasKeyWithError(mapping, key)); +} + +static PyObject * +mapping_haskeystringwitherror(PyObject *self, PyObject *args) +{ + PyObject *mapping; + const char *key; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "Oz#", &mapping, &key, &size)) { + return NULL; + } + NULLABLE(mapping); + RETURN_INT(PyMapping_HasKeyStringWithError(mapping, key)); +} + +static PyObject * object_setitem(PyObject *self, PyObject *args) { PyObject *mapping, *key, *value; @@ -568,6 +618,8 @@ static PyMethodDef test_methods[] = { {"object_getoptionalattrstring", object_getoptionalattrstring, METH_VARARGS}, {"object_hasattr", object_hasattr, METH_VARARGS}, {"object_hasattrstring", object_hasattrstring, METH_VARARGS}, + {"object_hasattrwitherror", object_hasattrwitherror, METH_VARARGS}, + {"object_hasattrstringwitherror", object_hasattrstringwitherror, METH_VARARGS}, {"object_setattr", object_setattr, METH_VARARGS}, {"object_setattrstring", object_setattrstring, METH_VARARGS}, {"object_delattr", object_delattr, METH_VARARGS}, @@ -582,6 +634,8 @@ static PyMethodDef test_methods[] = { {"mapping_getoptionalitemstring", mapping_getoptionalitemstring, METH_VARARGS}, {"mapping_haskey", mapping_haskey, METH_VARARGS}, {"mapping_haskeystring", mapping_haskeystring, METH_VARARGS}, + {"mapping_haskeywitherror", mapping_haskeywitherror, METH_VARARGS}, + {"mapping_haskeystringwitherror", mapping_haskeystringwitherror, METH_VARARGS}, {"object_setitem", object_setitem, METH_VARARGS}, {"mapping_setitemstring", mapping_setitemstring, METH_VARARGS}, {"object_delitem", object_delitem, METH_VARARGS}, diff --git a/Modules/_xxinterpchannelsmodule.c b/Modules/_xxinterpchannelsmodule.c index 1e41841..60ac8ed 100644 --- a/Modules/_xxinterpchannelsmodule.c +++ b/Modules/_xxinterpchannelsmodule.c @@ -123,7 +123,7 @@ get_module_from_type(PyTypeObject *cls) static PyObject * add_new_exception(PyObject *mod, const char *name, PyObject *base) { - assert(!PyObject_HasAttrString(mod, name)); + assert(!PyObject_HasAttrStringWithError(mod, name)); PyObject *exctype = PyErr_NewException(name, base, NULL); if (exctype == NULL) { return NULL; diff --git a/Modules/_xxsubinterpretersmodule.c b/Modules/_xxsubinterpretersmodule.c index 6638c2c..2dd8d9a 100644 --- a/Modules/_xxsubinterpretersmodule.c +++ b/Modules/_xxsubinterpretersmodule.c @@ -41,7 +41,7 @@ _get_current_interp(void) static PyObject * add_new_exception(PyObject *mod, const char *name, PyObject *base) { - assert(!PyObject_HasAttrString(mod, name)); + assert(!PyObject_HasAttrStringWithError(mod, name)); PyObject *exctype = PyErr_NewException(name, base, NULL); if (exctype == NULL) { return NULL; |