Commit ba9a6366 authored by Stefan Behnel's avatar Stefan Behnel Committed by GitHub

Merge pull request #2769 from cython/faster_getattr

Speed up attribute lookups that do not care about the AttributeError
parents 4e35b1a3 de109c20
......@@ -167,7 +167,7 @@ bad:
static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *, PyObject *, PyObject *); /*proto*/
//////////////////// GetAttr3 ////////////////////
//@requires: ObjectHandling.c::GetAttr
//@requires: ObjectHandling.c::PyObjectGetAttrStr
//@requires: Exceptions.c::PyThreadStateGet
//@requires: Exceptions.c::PyErrFetchRestore
//@requires: Exceptions.c::PyErrExceptionMatches
......@@ -183,7 +183,17 @@ static PyObject *__Pyx_GetAttr3Default(PyObject *d) {
}
static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *o, PyObject *n, PyObject *d) {
PyObject *r = __Pyx_GetAttr(o, n);
PyObject *r;
#if CYTHON_USE_TYPE_SLOTS
if (likely(PyString_Check(n))) {
r = __Pyx_PyObject_GetAttrStrNoError(o, n);
if (unlikely(!r) && likely(!PyErr_Occurred())) {
r = __Pyx_NewRef(d);
}
return r;
}
#endif
r = PyObject_GetAttr(o, n);
return (likely(r)) ? r : __Pyx_GetAttr3Default(d);
}
......
......@@ -485,6 +485,7 @@ static int __pyx_Generator_init(void); /*proto*/
//@requires: Exceptions.c::SaveResetException
//@requires: ObjectHandling.c::PyObjectCallMethod1
//@requires: ObjectHandling.c::PyObjectGetAttrStr
//@requires: ObjectHandling.c::PyObjectGetAttrStrNoError
//@requires: CommonStructures.c::FetchCommonType
#include <structmember.h>
......@@ -894,12 +895,11 @@ static int __Pyx_Coroutine_CloseIter(__pyx_CoroutineObject *gen, PyObject *yf) {
{
PyObject *meth;
gen->is_running = 1;
meth = __Pyx_PyObject_GetAttrStr(yf, PYIDENT("close"));
meth = __Pyx_PyObject_GetAttrStrNoError(yf, PYIDENT("close"));
if (unlikely(!meth)) {
if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
if (unlikely(PyErr_Occurred())) {
PyErr_WriteUnraisable(yf);
}
PyErr_Clear();
} else {
retval = PyObject_CallFunction(meth, NULL);
Py_DECREF(meth);
......@@ -1041,14 +1041,13 @@ static PyObject *__Pyx__Coroutine_Throw(PyObject *self, PyObject *typ, PyObject
ret = __Pyx__Coroutine_Throw(((__pyx_CoroutineAwaitObject*)yf)->coroutine, typ, val, tb, args, close_on_genexit);
#endif
} else {
PyObject *meth = __Pyx_PyObject_GetAttrStr(yf, PYIDENT("throw"));
PyObject *meth = __Pyx_PyObject_GetAttrStrNoError(yf, PYIDENT("throw"));
if (unlikely(!meth)) {
Py_DECREF(yf);
if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
if (unlikely(PyErr_Occurred())) {
gen->is_running = 0;
return NULL;
}
PyErr_Clear();
__Pyx_Coroutine_Undelegate(gen);
gen->is_running = 0;
goto throw_here;
......
......@@ -641,7 +641,7 @@ static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line);/*proto*/
#endif
/////////////// CLineInTraceback ///////////////
//@requires: ObjectHandling.c::PyObjectGetAttrStr
//@requires: ObjectHandling.c::PyObjectGetAttrStrNoError
//@requires: PyErrFetchRestore
//@substitute: naming
......@@ -669,7 +669,7 @@ static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line) {
} else
#endif
{
PyObject *use_cline_obj = __Pyx_PyObject_GetAttrStr(${cython_runtime_cname}, PYIDENT("cline_in_traceback"));
PyObject *use_cline_obj = __Pyx_PyObject_GetAttrStrNoError(${cython_runtime_cname}, PYIDENT("cline_in_traceback"));
if (use_cline_obj) {
use_cline = PyObject_Not(use_cline_obj) ? Py_False : Py_True;
Py_DECREF(use_cline_obj);
......
......@@ -132,6 +132,7 @@ static void __Pyx_call_next_tp_clear(PyObject* obj, inquiry current_tp_clear) {
static int __Pyx_setup_reduce(PyObject* type_obj);
/////////////// SetupReduce ///////////////
//@requires: ObjectHandling.c::PyObjectGetAttrStrNoError
//@requires: ObjectHandling.c::PyObjectGetAttrStr
//@substitute: naming
......@@ -139,7 +140,7 @@ static int __Pyx_setup_reduce_is_named(PyObject* meth, PyObject* name) {
int ret;
PyObject *name_attr;
name_attr = __Pyx_PyObject_GetAttrStr(meth, PYIDENT("__name__"));
name_attr = __Pyx_PyObject_GetAttrStrNoError(meth, PYIDENT("__name__"));
if (likely(name_attr)) {
ret = PyObject_RichCompareBool(name_attr, name, Py_EQ);
} else {
......@@ -192,7 +193,7 @@ static int __Pyx_setup_reduce(PyObject* type_obj) {
ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, PYIDENT("__reduce__"), reduce_cython); if (unlikely(ret < 0)) goto BAD;
ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, PYIDENT("__reduce_cython__")); if (unlikely(ret < 0)) goto BAD;
setstate = __Pyx_PyObject_GetAttrStr(type_obj, PYIDENT("__setstate__"));
setstate = __Pyx_PyObject_GetAttrStrNoError(type_obj, PYIDENT("__setstate__"));
if (!setstate) PyErr_Clear();
if (!setstate || __Pyx_setup_reduce_is_named(setstate, PYIDENT("__setstate_cython__"))) {
setstate_cython = __Pyx_PyObject_GetAttrStr(type_obj, PYIDENT("__setstate_cython__")); if (unlikely(!setstate_cython)) goto BAD;
......
......@@ -943,14 +943,14 @@ static PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObj
PyObject *mkw, int calculate_metaclass, int allow_py2_metaclass); /*proto*/
/////////////// Py3ClassCreate ///////////////
//@requires: PyObjectGetAttrStr
//@requires: PyObjectGetAttrStrNoError
//@requires: CalculateMetaclass
static PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name,
PyObject *qualname, PyObject *mkw, PyObject *modname, PyObject *doc) {
PyObject *ns;
if (metaclass) {
PyObject *prep = __Pyx_PyObject_GetAttrStr(metaclass, PYIDENT("__prepare__"));
PyObject *prep = __Pyx_PyObject_GetAttrStrNoError(metaclass, PYIDENT("__prepare__"));
if (prep) {
PyObject *pargs = PyTuple_Pack(2, name, bases);
if (unlikely(!pargs)) {
......@@ -961,9 +961,8 @@ static PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases,
Py_DECREF(prep);
Py_DECREF(pargs);
} else {
if (unlikely(!PyErr_ExceptionMatches(PyExc_AttributeError)))
if (unlikely(PyErr_Occurred()))
return NULL;
PyErr_Clear();
ns = PyDict_New();
}
} else {
......@@ -1099,12 +1098,12 @@ static CYTHON_INLINE PyObject* __Pyx_PyBoolOrNull_FromLong(long b) {
static PyObject *__Pyx_GetBuiltinName(PyObject *name); /*proto*/
/////////////// GetBuiltinName ///////////////
//@requires: PyObjectGetAttrStr
//@requires: PyObjectGetAttrStrNoError
//@substitute: naming
static PyObject *__Pyx_GetBuiltinName(PyObject *name) {
PyObject* result = __Pyx_PyObject_GetAttrStr($builtins_cname, name);
if (unlikely(!result)) {
PyObject* result = __Pyx_PyObject_GetAttrStrNoError($builtins_cname, name);
if (unlikely(!result) && !PyErr_Occurred()) {
PyErr_Format(PyExc_NameError,
#if PY_MAJOR_VERSION >= 3
"name '%U' is not defined", name);
......@@ -1121,28 +1120,17 @@ static PyObject *__Pyx_GetBuiltinName(PyObject *name) {
static PyObject *__Pyx__GetNameInClass(PyObject *nmspace, PyObject *name); /*proto*/
/////////////// GetNameInClass ///////////////
//@requires: PyObjectGetAttrStr
//@requires: PyObjectGetAttrStrNoError
//@requires: GetModuleGlobalName
//@requires: Exceptions.c::PyThreadStateGet
//@requires: Exceptions.c::PyErrFetchRestore
//@requires: Exceptions.c::PyErrExceptionMatches
static PyObject *__Pyx_GetGlobalNameAfterAttributeLookup(PyObject *name) {
PyObject *result;
__Pyx_PyThreadState_declare
__Pyx_PyThreadState_assign
if (unlikely(!__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError)))
return NULL;
__Pyx_PyErr_Clear();
__Pyx_GetModuleGlobalNameUncached(result, name);
return result;
}
static PyObject *__Pyx__GetNameInClass(PyObject *nmspace, PyObject *name) {
PyObject *result;
result = __Pyx_PyObject_GetAttrStr(nmspace, name);
result = __Pyx_PyObject_GetAttrStrNoError(nmspace, name);
if (!result) {
result = __Pyx_GetGlobalNameAfterAttributeLookup(name);
if (unlikely(PyErr_Occurred()))
return NULL;
__Pyx_GetModuleGlobalNameUncached(result, name);
return result;
}
return result;
}
......@@ -1358,6 +1346,41 @@ static PyObject* __Pyx_PyObject_GenericGetAttr(PyObject* obj, PyObject* attr_nam
#endif
/////////////// PyObjectGetAttrStrNoError.proto ///////////////
static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name);/*proto*/
/////////////// PyObjectGetAttrStrNoError ///////////////
//@requires: PyObjectGetAttrStr
//@requires: Exceptions.c::PyThreadStateGet
//@requires: Exceptions.c::PyErrFetchRestore
//@requires: Exceptions.c::PyErrExceptionMatches
static void __Pyx_PyObject_GetAttrStr_ClearAttributeError(void) {
__Pyx_PyThreadState_declare
__Pyx_PyThreadState_assign
if (likely(__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError)))
__Pyx_PyErr_Clear();
}
static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name) {
PyObject *result;
#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_TYPE_SLOTS && PY_VERSION_HEX >= 0x030700B1
// _PyObject_GenericGetAttrWithDict() in CPython 3.7+ can avoid raising the AttributeError.
// See https://bugs.python.org/issue32544
PyTypeObject* tp = Py_TYPE(obj);
if (likely(tp->tp_getattro == PyObject_GenericGetAttr)) {
return _PyObject_GenericGetAttrWithDict(obj, attr_name, NULL, 1);
}
#endif
result = __Pyx_PyObject_GetAttrStr(obj, attr_name);
if (unlikely(!result)) {
__Pyx_PyObject_GetAttrStr_ClearAttributeError();
}
return result;
}
/////////////// PyObjectGetAttrStr.proto ///////////////
#if CYTHON_USE_TYPE_SLOTS
......@@ -2303,7 +2326,7 @@ static PyObject* __Pyx_PyNumber_InPlaceMatrixMultiply(PyObject* x, PyObject* y);
#endif
/////////////// MatrixMultiply ///////////////
//@requires: PyObjectGetAttrStr
//@requires: PyObjectGetAttrStrNoError
//@requires: PyObjectCallOneArg
//@requires: PyFunctionFastCall
//@requires: PyCFunctionFastCall
......@@ -2353,17 +2376,15 @@ done:
return result;
}
#define __Pyx_TryMatrixMethod(x, y, py_method_name) { \
PyObject *func = __Pyx_PyObject_GetAttrStr(x, py_method_name); \
#define __Pyx_TryMatrixMethod(x, y, py_method_name) { \
PyObject *func = __Pyx_PyObject_GetAttrStrNoError(x, py_method_name); \
if (func) { \
PyObject *result = __Pyx_PyObject_CallMatrixMethod(func, y); \
if (result != Py_NotImplemented) \
return result; \
Py_DECREF(result); \
} else { \
if (!PyErr_ExceptionMatches(PyExc_AttributeError)) \
return NULL; \
PyErr_Clear(); \
} else if (unlikely(PyErr_Occurred())) { \
return NULL; \
} \
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment