From 96a9cdf007014d062c7b4c68a44f3908eb1fc635 Mon Sep 17 00:00:00 2001 From: "benjamin.peterson" Date: Sat, 9 May 2009 17:21:13 +0000 Subject: [PATCH] Merged revisions 72495 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r72495 | benjamin.peterson | 2009-05-08 21:07:04 -0500 (Fri, 08 May 2009) | 1 line lookup __reversed__ correctly as a special method ........ git-svn-id: http://svn.python.org/projects/python/branches/py3k@72511 6015fed2-1504-0410-9fe1-9d1591cc4771 --- Lib/test/test_descr.py | 3 +++ Objects/enumobject.c | 11 ++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index 37cab01f88..b4bd948f82 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -1549,12 +1549,15 @@ order (MRO) for bases """ return self def hello(self): return b"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 = [ ("__bytes__", bytes, 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. diff --git a/Objects/enumobject.c b/Objects/enumobject.c index 955bbdc671..f8e407282e 100644 --- a/Objects/enumobject.c +++ b/Objects/enumobject.c @@ -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, -- 2.11.4.GIT