From da2cf04c2807e3b2f80e06306242238ddddaa260 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sat, 5 Jun 2010 00:45:37 +0000 Subject: [PATCH] Merged revisions 81706-81707 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r81706 | benjamin.peterson | 2010-06-04 19:32:50 -0500 (Fri, 04 Jun 2010) | 1 line properly lookup the __format__ special method ........ r81707 | benjamin.peterson | 2010-06-04 19:38:22 -0500 (Fri, 04 Jun 2010) | 1 line remove PyType_Ready call; float should be initialized in interpreter startup ........ --- Lib/test/test_descr.py | 3 +++ Objects/abstract.c | 42 +++++++++++++++--------------------------- 2 files changed, 18 insertions(+), 27 deletions(-) diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index 5568dd5e279..10820ab712e 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -1557,6 +1557,8 @@ order (MRO) for bases """ self.assertEqual(key, "hi") return 4 def swallow(*args): pass + def format_impl(self, spec): + return "hello" # 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 @@ -1575,6 +1577,7 @@ order (MRO) for bases """ ("__enter__", run_context, iden, set(), {"__exit__" : swallow}), ("__exit__", run_context, swallow, set(), {"__enter__" : iden}), ("__complex__", complex, complex_num, set(), {}), + ("__format__", format, format_impl, set(), {}), ] class Checker(object): diff --git a/Objects/abstract.c b/Objects/abstract.c index 5a904b44d12..1b6c2b42796 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -693,48 +693,36 @@ PyBuffer_Release(Py_buffer *view) PyObject * PyObject_Format(PyObject *obj, PyObject *format_spec) { - static PyObject * str__format__ = NULL; PyObject *meth; PyObject *empty = NULL; PyObject *result = NULL; - - /* Initialize cached value */ - if (str__format__ == NULL) { - /* Initialize static variable needed by _PyType_Lookup */ - str__format__ = PyUnicode_FromString("__format__"); - if (str__format__ == NULL) - goto done; - } + static PyObject *format_cache = NULL; /* If no format_spec is provided, use an empty string */ if (format_spec == NULL) { - empty = PyUnicode_FromUnicode(NULL, 0); - format_spec = empty; + empty = PyUnicode_FromUnicode(NULL, 0); + format_spec = empty; } - /* Make sure the type is initialized. float gets initialized late */ - if (Py_TYPE(obj)->tp_dict == NULL) - if (PyType_Ready(Py_TYPE(obj)) < 0) - goto done; - /* Find the (unbound!) __format__ method (a borrowed reference) */ - meth = _PyType_Lookup(Py_TYPE(obj), str__format__); + meth = _PyObject_LookupSpecial(obj, "__format__", &format_cache); if (meth == NULL) { - PyErr_Format(PyExc_TypeError, - "Type %.100s doesn't define __format__", - Py_TYPE(obj)->tp_name); + if (!PyErr_Occurred()) + PyErr_Format(PyExc_TypeError, + "Type %.100s doesn't define __format__", + Py_TYPE(obj)->tp_name); goto done; } - /* And call it, binding it to the value */ - result = PyObject_CallFunctionObjArgs(meth, obj, format_spec, NULL); + /* And call it. */ + result = PyObject_CallFunctionObjArgs(meth, format_spec, NULL); if (result && !PyUnicode_Check(result)) { - PyErr_SetString(PyExc_TypeError, - "__format__ method did not return string"); - Py_DECREF(result); - result = NULL; - goto done; + PyErr_SetString(PyExc_TypeError, + "__format__ method did not return string"); + Py_DECREF(result); + result = NULL; + goto done; } done: