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 /Objects | |
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 'Objects')
-rw-r--r-- | Objects/abstract.c | 18 | ||||
-rw-r--r-- | Objects/dictobject.c | 7 | ||||
-rw-r--r-- | Objects/genericaliasobject.c | 35 | ||||
-rw-r--r-- | Objects/object.c | 47 | ||||
-rw-r--r-- | Objects/typeobject.c | 8 | ||||
-rw-r--r-- | Objects/unionobject.c | 27 |
6 files changed, 73 insertions, 69 deletions
diff --git a/Objects/abstract.c b/Objects/abstract.c index b57190d..55d3b3a 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -2427,6 +2427,24 @@ PyMapping_SetItemString(PyObject *o, const char *key, PyObject *value) } int +PyMapping_HasKeyStringWithError(PyObject *obj, const char *key) +{ + PyObject *res; + int rc = PyMapping_GetOptionalItemString(obj, key, &res); + Py_XDECREF(res); + return rc; +} + +int +PyMapping_HasKeyWithError(PyObject *obj, PyObject *key) +{ + PyObject *res; + int rc = PyMapping_GetOptionalItem(obj, key, &res); + Py_XDECREF(res); + return rc; +} + +int PyMapping_HasKeyString(PyObject *o, const char *key) { PyObject *v; diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 329581c..1fb795f 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -2688,12 +2688,11 @@ dict_update_arg(PyObject *self, PyObject *arg) if (PyDict_CheckExact(arg)) { return PyDict_Merge(self, arg, 1); } - PyObject *func; - if (PyObject_GetOptionalAttr(arg, &_Py_ID(keys), &func) < 0) { + int has_keys = PyObject_HasAttrWithError(arg, &_Py_ID(keys)); + if (has_keys < 0) { return -1; } - if (func != NULL) { - Py_DECREF(func); + if (has_keys) { return PyDict_Merge(self, arg, 1); } return PyDict_MergeFromSeq2(self, arg, 1); diff --git a/Objects/genericaliasobject.c b/Objects/genericaliasobject.c index ca17244..bf13ed3 100644 --- a/Objects/genericaliasobject.c +++ b/Objects/genericaliasobject.c @@ -55,8 +55,7 @@ ga_repr_item(_PyUnicodeWriter *writer, PyObject *p) PyObject *qualname = NULL; PyObject *module = NULL; PyObject *r = NULL; - PyObject *tmp; - int err; + int rc; if (p == Py_Ellipsis) { // The Ellipsis object @@ -64,19 +63,14 @@ ga_repr_item(_PyUnicodeWriter *writer, PyObject *p) goto done; } - if (PyObject_GetOptionalAttr(p, &_Py_ID(__origin__), &tmp) < 0) { - goto done; + if ((rc = PyObject_HasAttrWithError(p, &_Py_ID(__origin__))) > 0 && + (rc = PyObject_HasAttrWithError(p, &_Py_ID(__args__))) > 0) + { + // It looks like a GenericAlias + goto use_repr; } - if (tmp != NULL) { - Py_DECREF(tmp); - if (PyObject_GetOptionalAttr(p, &_Py_ID(__args__), &tmp) < 0) { - goto done; - } - if (tmp != NULL) { - Py_DECREF(tmp); - // It looks like a GenericAlias - goto use_repr; - } + if (rc < 0) { + goto done; } if (PyObject_GetOptionalAttr(p, &_Py_ID(__qualname__), &qualname) < 0) { @@ -113,13 +107,13 @@ done: Py_XDECREF(module); if (r == NULL) { // error if any of the above PyObject_Repr/PyUnicode_From* fail - err = -1; + rc = -1; } else { - err = _PyUnicodeWriter_WriteStr(writer, r); + rc = _PyUnicodeWriter_WriteStr(writer, r); Py_DECREF(r); } - return err; + return rc; } static int @@ -253,18 +247,17 @@ _Py_make_parameters(PyObject *args) Py_ssize_t iparam = 0; for (Py_ssize_t iarg = 0; iarg < nargs; iarg++) { PyObject *t = PyTuple_GET_ITEM(args, iarg); - PyObject *subst; // We don't want __parameters__ descriptor of a bare Python class. if (PyType_Check(t)) { continue; } - if (PyObject_GetOptionalAttr(t, &_Py_ID(__typing_subst__), &subst) < 0) { + int rc = PyObject_HasAttrWithError(t, &_Py_ID(__typing_subst__)); + if (rc < 0) { Py_DECREF(parameters); return NULL; } - if (subst) { + if (rc) { iparam += tuple_add(parameters, iparam, t); - Py_DECREF(subst); } else { PyObject *subparams; diff --git a/Objects/object.c b/Objects/object.c index 7aeda50..15c2bf6 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -911,26 +911,24 @@ PyObject_GetAttrString(PyObject *v, const char *name) } int -PyObject_HasAttrString(PyObject *v, const char *name) +PyObject_HasAttrStringWithError(PyObject *obj, const char *name) { - if (Py_TYPE(v)->tp_getattr != NULL) { - PyObject *res = (*Py_TYPE(v)->tp_getattr)(v, (char*)name); - if (res != NULL) { - Py_DECREF(res); - return 1; - } - PyErr_Clear(); - return 0; - } + PyObject *res; + int rc = PyObject_GetOptionalAttrString(obj, name, &res); + Py_XDECREF(res); + return rc; +} + - PyObject *attr_name = PyUnicode_FromString(name); - if (attr_name == NULL) { +int +PyObject_HasAttrString(PyObject *obj, const char *name) +{ + int rc = PyObject_HasAttrStringWithError(obj, name); + if (rc < 0) { PyErr_Clear(); return 0; } - int ok = PyObject_HasAttr(v, attr_name); - Py_DECREF(attr_name); - return ok; + return rc; } int @@ -1149,18 +1147,23 @@ PyObject_GetOptionalAttrString(PyObject *obj, const char *name, PyObject **resul } int -PyObject_HasAttr(PyObject *v, PyObject *name) +PyObject_HasAttrWithError(PyObject *obj, PyObject *name) { PyObject *res; - if (PyObject_GetOptionalAttr(v, name, &res) < 0) { + int rc = PyObject_GetOptionalAttr(obj, name, &res); + Py_XDECREF(res); + return rc; +} + +int +PyObject_HasAttr(PyObject *obj, PyObject *name) +{ + int rc = PyObject_HasAttrWithError(obj, name); + if (rc < 0) { PyErr_Clear(); return 0; } - if (res == NULL) { - return 0; - } - Py_DECREF(res); - return 1; + return rc; } int diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 84c5050..893d842 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -3879,16 +3879,14 @@ type_new_get_bases(type_new_ctx *ctx, PyObject **type) if (PyType_Check(base)) { continue; } - PyObject *mro_entries; - if (PyObject_GetOptionalAttr(base, &_Py_ID(__mro_entries__), - &mro_entries) < 0) { + int rc = PyObject_HasAttrWithError(base, &_Py_ID(__mro_entries__)); + if (rc < 0) { return -1; } - if (mro_entries != NULL) { + if (rc) { PyErr_SetString(PyExc_TypeError, "type() doesn't support MRO entry resolution; " "use types.new_class()"); - Py_DECREF(mro_entries); return -1; } } diff --git a/Objects/unionobject.c b/Objects/unionobject.c index 3493ab3..bf56056 100644 --- a/Objects/unionobject.c +++ b/Objects/unionobject.c @@ -186,28 +186,21 @@ union_repr_item(_PyUnicodeWriter *writer, PyObject *p) { PyObject *qualname = NULL; PyObject *module = NULL; - PyObject *tmp; PyObject *r = NULL; - int err; + int rc; if (p == (PyObject *)&_PyNone_Type) { return _PyUnicodeWriter_WriteASCIIString(writer, "None", 4); } - if (PyObject_GetOptionalAttr(p, &_Py_ID(__origin__), &tmp) < 0) { - goto exit; + if ((rc = PyObject_HasAttrWithError(p, &_Py_ID(__origin__))) > 0 && + (rc = PyObject_HasAttrWithError(p, &_Py_ID(__args__))) > 0) + { + // It looks like a GenericAlias + goto use_repr; } - - if (tmp) { - Py_DECREF(tmp); - if (PyObject_GetOptionalAttr(p, &_Py_ID(__args__), &tmp) < 0) { - goto exit; - } - if (tmp) { - // It looks like a GenericAlias - Py_DECREF(tmp); - goto use_repr; - } + if (rc < 0) { + goto exit; } if (PyObject_GetOptionalAttr(p, &_Py_ID(__qualname__), &qualname) < 0) { @@ -244,9 +237,9 @@ exit: if (r == NULL) { return -1; } - err = _PyUnicodeWriter_WriteStr(writer, r); + rc = _PyUnicodeWriter_WriteStr(writer, r); Py_DECREF(r); - return err; + return rc; } static PyObject * |