diff options
author | Eric Smith <eric@trueblade.com> | 2008-02-17 19:48:00 (GMT) |
---|---|---|
committer | Eric Smith <eric@trueblade.com> | 2008-02-17 19:48:00 (GMT) |
commit | 8fd3eba0501a77eec463179f529f56025ff4b40b (patch) | |
tree | d459220bd52a30ce3de89b89ed1db077e7b5d4a4 /Objects/abstract.c | |
parent | 18c66898b0a14761786161c07d89d65c8f088601 (diff) | |
download | cpython-8fd3eba0501a77eec463179f529f56025ff4b40b.zip cpython-8fd3eba0501a77eec463179f529f56025ff4b40b.tar.gz cpython-8fd3eba0501a77eec463179f529f56025ff4b40b.tar.bz2 |
Fixes for shared 2.6 code that implements PEP 3101, advanced string
formatting.
Includes:
- Modifying tests for basic types to use __format__ methods, instead
of builtin "format".
- Adding PyObject_Format.
- General str/unicode cleanup discovered when backporting to 2.6.
- Removing datetimemodule.c's time_format, since it was identical
to date_format.
The files in Objects/stringlib that implement PEP 3101 (stringdefs.h,
unicodedefs.h, formatter.h, string_format.h) are identical in trunk
and py3k. Any changes from here on should be made to trunk, and
changes will propogate to py3k).
Diffstat (limited to 'Objects/abstract.c')
-rw-r--r-- | Objects/abstract.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/Objects/abstract.c b/Objects/abstract.c index bb6c301..655a52a 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -704,6 +704,57 @@ PyBuffer_FillInfo(Py_buffer *view, void *buf, Py_ssize_t len, return 0; } +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; + } + + /* If no format_spec is provided, use an empty string */ + if (format_spec == NULL) { + 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__); + if (meth == NULL) { + 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); + + if (result && !PyUnicode_Check(result)) { + PyErr_SetString(PyExc_TypeError, + "__format__ method did not return string"); + Py_DECREF(result); + result = NULL; + goto done; + } + +done: + Py_XDECREF(empty); + return result; +} /* Operations on numbers */ int |