diff options
author | Jeremy Hylton <jeremy@alum.mit.edu> | 2001-05-11 14:48:41 (GMT) |
---|---|---|
committer | Jeremy Hylton <jeremy@alum.mit.edu> | 2001-05-11 14:48:41 (GMT) |
commit | 1b0feb4ada9b1ff604f9d3100254f9071a96713f (patch) | |
tree | 937bae85551e5eb1c1583df03af0fe1702df713f | |
parent | 6278799f8e34bf01de68f989f5f100913fb5e2f5 (diff) | |
download | cpython-1b0feb4ada9b1ff604f9d3100254f9071a96713f.zip cpython-1b0feb4ada9b1ff604f9d3100254f9071a96713f.tar.gz cpython-1b0feb4ada9b1ff604f9d3100254f9071a96713f.tar.bz2 |
Variant of SF patch 423181
For rich comparisons, use instance_getattr2() when possible to avoid
the expense of setting an AttributeError. Also intern the name_op[]
table and use the interned strings rather than creating a new string
and interning it each time through.
-rw-r--r-- | Objects/classobject.c | 72 |
1 files changed, 51 insertions, 21 deletions
diff --git a/Objects/classobject.c b/Objects/classobject.c index 67732ca..43d2890 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -1651,38 +1651,68 @@ instance_ipow(PyObject *v, PyObject *w, PyObject *z) /* Map rich comparison operators to their __xx__ namesakes */ -static char *name_op[] = { - "__lt__", - "__le__", - "__eq__", - "__ne__", - "__gt__", - "__ge__", -}; +#define NAME_OPS 6 +static PyObject **name_op = NULL; + +static int +init_name_op() +{ + int i; + char *_name_op[] = { + "__lt__", + "__le__", + "__eq__", + "__ne__", + "__gt__", + "__ge__", + }; + + name_op = (PyObject **)malloc(sizeof(PyObject *) * NAME_OPS); + if (name_op == NULL) + return -1; + for (i = 0; i < NAME_OPS; ++i) { + name_op[i] = PyString_InternFromString(_name_op[i]); + if (name_op[i] == NULL) + return -1; + } + return 0; +} static PyObject * half_richcompare(PyObject *v, PyObject *w, int op) { - PyObject *name; PyObject *method; PyObject *args; PyObject *res; assert(PyInstance_Check(v)); - name = PyString_InternFromString(name_op[op]); - if (name == NULL) - return NULL; - - method = PyObject_GetAttr(v, name); - Py_DECREF(name); - if (method == NULL) { - if (!PyErr_ExceptionMatches(PyExc_AttributeError)) + if (name_op == NULL) { + if (init_name_op() < 0) return NULL; - PyErr_Clear(); - res = Py_NotImplemented; - Py_INCREF(res); - return res; + } + /* If the instance doesn't define an __getattr__ method, use + instance_getattr2 directly because it will not set an + exception on failure. */ + if (((PyInstanceObject *)v)->in_class->cl_getattr == NULL) { + method = instance_getattr2((PyInstanceObject *)v, + name_op[op]); + if (method == NULL) { + assert(!PyErr_Occurred()); + res = Py_NotImplemented; + Py_INCREF(res); + return res; + } + } else { + method = PyObject_GetAttr(v, name_op[op]); + if (method == NULL) { + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) + return NULL; + PyErr_Clear(); + res = Py_NotImplemented; + Py_INCREF(res); + return res; + } } args = Py_BuildValue("(O)", w); |