]> granicus.if.org Git - python/commitdiff
lookup __reversed__ correctly as a special method
authorBenjamin Peterson <benjamin@python.org>
Sat, 9 May 2009 02:07:04 +0000 (02:07 +0000)
committerBenjamin Peterson <benjamin@python.org>
Sat, 9 May 2009 02:07:04 +0000 (02:07 +0000)
Lib/test/test_descr.py
Objects/enumobject.c

index 2b00ce9ea6e9704093c8c2658d7404ea82b46fdd..fe4eaeae8855e679b2d79e4b497f998778f490a5 100644 (file)
@@ -1676,12 +1676,15 @@ order (MRO) for bases """
             return self
         def hello(self):
             return "hello"
+        def empty_seq(self):
+            return []
 
         # It would be nice to have every special method tested here, but I'm
         # only listing the ones I can remember outside of typeobject.c, since it
         # does it right.
         specials = [
             ("__unicode__", unicode, hello),
+            ("__reversed__", reversed, empty_seq),
             # These two fail because the compiler generates LOAD_ATTR to look
             # them up.  We'd have to add a new opcode to fix this, and it's
             # probably not worth it.
index b1e412d9bf39772e65ed383dc2d81e80ddf26281..12a226c74836de9a5d8d62eec88e9c0432436138 100644 (file)
@@ -222,7 +222,8 @@ static PyObject *
 reversed_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 {
        Py_ssize_t n;
-       PyObject *seq;
+       PyObject *seq, *reversed_meth;
+       static PyObject *reversed_cache = NULL;
        reversedobject *ro;
 
        if (type == &PyReversed_Type && !_PyArg_NoKeywords("reversed()", kwds))
@@ -231,8 +232,12 @@ reversed_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
        if (!PyArg_UnpackTuple(args, "reversed", 1, 1, &seq) )
                return NULL;
 
-       if (PyObject_HasAttrString(seq, "__reversed__"))
-               return PyObject_CallMethod(seq, "__reversed__", NULL);
+       reversed_meth = _PyObject_LookupSpecial(seq, "__reversed__", &reversed_cache);
+       if (reversed_meth != NULL) {
+               PyObject *res = PyObject_CallFunctionObjArgs(reversed_meth, NULL);
+               Py_DECREF(reversed_meth);
+               return res;
+       }
 
        if (!PySequence_Check(seq)) {
                PyErr_SetString(PyExc_TypeError,