summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Hylton <jeremy@alum.mit.edu>2001-05-11 14:48:41 (GMT)
committerJeremy Hylton <jeremy@alum.mit.edu>2001-05-11 14:48:41 (GMT)
commit1b0feb4ada9b1ff604f9d3100254f9071a96713f (patch)
tree937bae85551e5eb1c1583df03af0fe1702df713f
parent6278799f8e34bf01de68f989f5f100913fb5e2f5 (diff)
downloadcpython-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.c72
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);