summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2023-09-17 11:23:31 (GMT)
committerGitHub <noreply@github.com>2023-09-17 11:23:31 (GMT)
commitadd16f1a5e4013f97d33cc677dc008e8199f5b11 (patch)
tree2c187adbae2766f942e35780950a526dfe84ff48 /Objects
parente57ecf6bbc59f999d27b125ea51b042c24a07bd9 (diff)
downloadcpython-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.c18
-rw-r--r--Objects/dictobject.c7
-rw-r--r--Objects/genericaliasobject.c35
-rw-r--r--Objects/object.c47
-rw-r--r--Objects/typeobject.c8
-rw-r--r--Objects/unionobject.c27
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 *