summaryrefslogtreecommitdiffstats
path: root/Python/bltinmodule.c
diff options
context:
space:
mode:
authorINADA Naoki <methane@users.noreply.github.com>2018-01-16 11:52:41 (GMT)
committerGitHub <noreply@github.com>2018-01-16 11:52:41 (GMT)
commit378edee0a3b913d60653dc17dfe61d83405a8135 (patch)
treee91c9b9b446aa0ce076da778bde6c1da27ff5e23 /Python/bltinmodule.c
parentb44c5169f64178d2ff2914187b315549e7ab0cb6 (diff)
downloadcpython-378edee0a3b913d60653dc17dfe61d83405a8135.zip
cpython-378edee0a3b913d60653dc17dfe61d83405a8135.tar.gz
cpython-378edee0a3b913d60653dc17dfe61d83405a8135.tar.bz2
bpo-32544: Speed up hasattr() and getattr() (GH-5173)
AttributeError was raised always when attribute is not found. This commit skip raising AttributeError when `tp_getattro` is `PyObject_GenericGetAttr`. It makes hasattr() and getattr() about 4x faster when attribute is not found.
Diffstat (limited to 'Python/bltinmodule.c')
-rw-r--r--Python/bltinmodule.c21
1 files changed, 11 insertions, 10 deletions
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index e702f7c..844548f 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -1126,13 +1126,15 @@ builtin_getattr(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
"getattr(): attribute name must be string");
return NULL;
}
- result = PyObject_GetAttr(v, name);
- if (result == NULL && dflt != NULL &&
- PyErr_ExceptionMatches(PyExc_AttributeError))
- {
- PyErr_Clear();
- Py_INCREF(dflt);
- result = dflt;
+ if (dflt != NULL) {
+ result = _PyObject_GetAttrWithoutError(v, name);
+ if (result == NULL && !PyErr_Occurred()) {
+ Py_INCREF(dflt);
+ return dflt;
+ }
+ }
+ else {
+ result = PyObject_GetAttr(v, name);
}
return result;
}
@@ -1189,10 +1191,9 @@ builtin_hasattr_impl(PyObject *module, PyObject *obj, PyObject *name)
"hasattr(): attribute name must be string");
return NULL;
}
- v = PyObject_GetAttr(obj, name);
+ v = _PyObject_GetAttrWithoutError(obj, name);
if (v == NULL) {
- if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
- PyErr_Clear();
+ if (!PyErr_Occurred()) {
Py_RETURN_FALSE;
}
return NULL;