summaryrefslogtreecommitdiffstats
path: root/Objects/abstract.c
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2018-01-25 08:49:40 (GMT)
committerINADA Naoki <methane@users.noreply.github.com>2018-01-25 08:49:40 (GMT)
commitf320be77ffb73e3b9e7fc98c37b8df3975d84b40 (patch)
tree552338f0200938249233fa4aa7b00add61965337 /Objects/abstract.c
parent2b822a0bb1de2612c85d8f75e3ce89eda2ac9f68 (diff)
downloadcpython-f320be77ffb73e3b9e7fc98c37b8df3975d84b40.zip
cpython-f320be77ffb73e3b9e7fc98c37b8df3975d84b40.tar.gz
cpython-f320be77ffb73e3b9e7fc98c37b8df3975d84b40.tar.bz2
bpo-32571: Avoid raising unneeded AttributeError and silencing it in C code (GH-5222)
Add two new private APIs: _PyObject_LookupAttr() and _PyObject_LookupAttrId()
Diffstat (limited to 'Objects/abstract.c')
-rw-r--r--Objects/abstract.c50
1 files changed, 17 insertions, 33 deletions
diff --git a/Objects/abstract.c b/Objects/abstract.c
index a68253b..93eda62 100644
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -171,16 +171,14 @@ PyObject_GetItem(PyObject *o, PyObject *key)
if (PyType_Check(o)) {
PyObject *meth, *result, *stack[1] = {key};
_Py_IDENTIFIER(__class_getitem__);
- meth = _PyObject_GetAttrId(o, &PyId___class_getitem__);
+ if (_PyObject_LookupAttrId(o, &PyId___class_getitem__, &meth) < 0) {
+ return NULL;
+ }
if (meth) {
result = _PyObject_FastCall(meth, stack, 1);
Py_DECREF(meth);
return result;
}
- else if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
- return NULL;
- }
- PyErr_Clear();
}
return type_error("'%.200s' object is not subscriptable", o);
@@ -2268,14 +2266,9 @@ abstract_get_bases(PyObject *cls)
PyObject *bases;
Py_ALLOW_RECURSION
- bases = _PyObject_GetAttrId(cls, &PyId___bases__);
+ (void)_PyObject_LookupAttrId(cls, &PyId___bases__, &bases);
Py_END_ALLOW_RECURSION
- if (bases == NULL) {
- if (PyErr_ExceptionMatches(PyExc_AttributeError))
- PyErr_Clear();
- return NULL;
- }
- if (!PyTuple_Check(bases)) {
+ if (bases != NULL && !PyTuple_Check(bases)) {
Py_DECREF(bases);
return NULL;
}
@@ -2338,26 +2331,23 @@ static int
recursive_isinstance(PyObject *inst, PyObject *cls)
{
PyObject *icls;
- int retval = 0;
+ int retval;
_Py_IDENTIFIER(__class__);
if (PyType_Check(cls)) {
retval = PyObject_TypeCheck(inst, (PyTypeObject *)cls);
if (retval == 0) {
- PyObject *c = _PyObject_GetAttrId(inst, &PyId___class__);
- if (c == NULL) {
- if (PyErr_ExceptionMatches(PyExc_AttributeError))
- PyErr_Clear();
- else
- retval = -1;
- }
- else {
- if (c != (PyObject *)(inst->ob_type) &&
- PyType_Check(c))
+ retval = _PyObject_LookupAttrId(inst, &PyId___class__, &icls);
+ if (icls != NULL) {
+ if (icls != (PyObject *)(inst->ob_type) && PyType_Check(icls)) {
retval = PyType_IsSubtype(
- (PyTypeObject *)c,
+ (PyTypeObject *)icls,
(PyTypeObject *)cls);
- Py_DECREF(c);
+ }
+ else {
+ retval = 0;
+ }
+ Py_DECREF(icls);
}
}
}
@@ -2365,14 +2355,8 @@ recursive_isinstance(PyObject *inst, PyObject *cls)
if (!check_class(cls,
"isinstance() arg 2 must be a type or tuple of types"))
return -1;
- icls = _PyObject_GetAttrId(inst, &PyId___class__);
- if (icls == NULL) {
- if (PyErr_ExceptionMatches(PyExc_AttributeError))
- PyErr_Clear();
- else
- retval = -1;
- }
- else {
+ retval = _PyObject_LookupAttrId(inst, &PyId___class__, &icls);
+ if (icls != NULL) {
retval = abstract_issubclass(icls, cls);
Py_DECREF(icls);
}