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
........
This commit is contained in:
Benjamin Peterson 2010-06-05 00:45:37 +00:00
parent 2d5157eb91
commit da2cf04c28
2 changed files with 18 additions and 27 deletions

View File

@ -1557,6 +1557,8 @@ order (MRO) for bases """
self.assertEqual(key, "hi") self.assertEqual(key, "hi")
return 4 return 4
def swallow(*args): pass 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 # 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 # 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}), ("__enter__", run_context, iden, set(), {"__exit__" : swallow}),
("__exit__", run_context, swallow, set(), {"__enter__" : iden}), ("__exit__", run_context, swallow, set(), {"__enter__" : iden}),
("__complex__", complex, complex_num, set(), {}), ("__complex__", complex, complex_num, set(), {}),
("__format__", format, format_impl, set(), {}),
] ]
class Checker(object): class Checker(object):

View File

@ -693,48 +693,36 @@ PyBuffer_Release(Py_buffer *view)
PyObject * PyObject *
PyObject_Format(PyObject *obj, PyObject *format_spec) PyObject_Format(PyObject *obj, PyObject *format_spec)
{ {
static PyObject * str__format__ = NULL;
PyObject *meth; PyObject *meth;
PyObject *empty = NULL; PyObject *empty = NULL;
PyObject *result = NULL; PyObject *result = NULL;
static PyObject *format_cache = 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;
}
/* If no format_spec is provided, use an empty string */ /* If no format_spec is provided, use an empty string */
if (format_spec == NULL) { if (format_spec == NULL) {
empty = PyUnicode_FromUnicode(NULL, 0); empty = PyUnicode_FromUnicode(NULL, 0);
format_spec = empty; 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) */ /* 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) { if (meth == NULL) {
PyErr_Format(PyExc_TypeError, if (!PyErr_Occurred())
"Type %.100s doesn't define __format__", PyErr_Format(PyExc_TypeError,
Py_TYPE(obj)->tp_name); "Type %.100s doesn't define __format__",
Py_TYPE(obj)->tp_name);
goto done; goto done;
} }
/* And call it, binding it to the value */ /* And call it. */
result = PyObject_CallFunctionObjArgs(meth, obj, format_spec, NULL); result = PyObject_CallFunctionObjArgs(meth, format_spec, NULL);
if (result && !PyUnicode_Check(result)) { if (result && !PyUnicode_Check(result)) {
PyErr_SetString(PyExc_TypeError, PyErr_SetString(PyExc_TypeError,
"__format__ method did not return string"); "__format__ method did not return string");
Py_DECREF(result); Py_DECREF(result);
result = NULL; result = NULL;
goto done; goto done;
} }
done: done: