diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2018-01-25 08:49:40 (GMT) |
---|---|---|
committer | INADA Naoki <methane@users.noreply.github.com> | 2018-01-25 08:49:40 (GMT) |
commit | f320be77ffb73e3b9e7fc98c37b8df3975d84b40 (patch) | |
tree | 552338f0200938249233fa4aa7b00add61965337 /Objects/abstract.c | |
parent | 2b822a0bb1de2612c85d8f75e3ce89eda2ac9f68 (diff) | |
download | cpython-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.c | 50 |
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); } |