diff options
author | Eric Smith <eric@trueblade.com> | 2008-02-17 19:48:00 +0000 |
---|---|---|
committer | Eric Smith <eric@trueblade.com> | 2008-02-17 19:48:00 +0000 |
commit | 8fd3eba0501a77eec463179f529f56025ff4b40b (patch) | |
tree | d459220bd52a30ce3de89b89ed1db077e7b5d4a4 /Objects/stringlib/string_format.h | |
parent | 18c66898b0a14761786161c07d89d65c8f088601 (diff) | |
download | cpython-8fd3eba0501a77eec463179f529f56025ff4b40b.tar.gz cpython-8fd3eba0501a77eec463179f529f56025ff4b40b.zip |
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/stringlib/string_format.h')
-rw-r--r-- | Objects/stringlib/string_format.h | 96 |
1 files changed, 24 insertions, 72 deletions
diff --git a/Objects/stringlib/string_format.h b/Objects/stringlib/string_format.h index 2c4510f98d6..70f8f13aea2 100644 --- a/Objects/stringlib/string_format.h +++ b/Objects/stringlib/string_format.h @@ -6,6 +6,11 @@ */ +/* Defines for Python 2.6 compatability */ +#if PY_VERSION_HEX < 0x03000000 +#define PyLong_FromSsize_t _PyLong_FromSsize_t +#endif + /* Defines for more efficiently reallocating the string buffer */ #define INITIAL_SIZE_INCREMENT 100 #define SIZE_MULTIPLIER 2 @@ -470,66 +475,6 @@ error: field object and field specification string generated by get_field_and_spec, and renders the field into the output string. - format() does the actual calling of the objects __format__ method. -*/ - - -/* returns fieldobj.__format__(format_spec) */ -static PyObject * -format(PyObject *fieldobj, SubString *format_spec) -{ - static PyObject *format_str = NULL; - PyObject *meth; - PyObject *spec = NULL; - PyObject *result = NULL; - - /* Initialize cached value */ - if (format_str == NULL) { - /* Initialize static variable needed by _PyType_Lookup */ - format_str = PyUnicode_FromString("__format__"); - if (format_str == NULL) - return NULL; - } - - /* Make sure the type is initialized. float gets initialized late */ - if (Py_TYPE(fieldobj)->tp_dict == NULL) - if (PyType_Ready(Py_TYPE(fieldobj)) < 0) - return NULL; - - /* we need to create an object out of the pointers we have */ - spec = SubString_new_object_or_empty(format_spec); - if (spec == NULL) - goto done; - - /* Find the (unbound!) __format__ method (a borrowed reference) */ - meth = _PyType_Lookup(Py_TYPE(fieldobj), format_str); - if (meth == NULL) { - PyErr_Format(PyExc_TypeError, - "Type %.100s doesn't define __format__", - Py_TYPE(fieldobj)->tp_name); - goto done; - } - - /* And call it, binding it to the value */ - result = PyObject_CallFunctionObjArgs(meth, fieldobj, spec, NULL); - if (result == NULL) - goto done; - - if (!STRINGLIB_CHECK(result)) { - PyErr_SetString(PyExc_TypeError, - "__format__ method did not return " - STRINGLIB_TYPE_NAME); - Py_DECREF(result); - result = NULL; - goto done; - } - -done: - Py_XDECREF(spec); - return result; -} - -/* render_field calls fieldobj.__format__(format_spec) method, and appends to the output. */ @@ -537,14 +482,21 @@ static int render_field(PyObject *fieldobj, SubString *format_spec, OutputString *output) { int ok = 0; - PyObject *result = format(fieldobj, format_spec); + PyObject *result = NULL; + /* we need to create an object out of the pointers we have */ + PyObject *format_spec_object = SubString_new_object_or_empty(format_spec); + if (format_spec_object == NULL) + goto done; + + result = PyObject_Format(fieldobj, format_spec_object); if (result == NULL) goto done; ok = output_data(output, STRINGLIB_STR(result), STRINGLIB_LEN(result)); done: + Py_DECREF(format_spec_object); Py_XDECREF(result); return ok; } @@ -770,7 +722,7 @@ do_conversion(PyObject *obj, STRINGLIB_CHAR conversion) case 'r': return PyObject_Repr(obj); case 's': - return PyObject_Str(obj); + return STRINGLIB_TOSTR(obj); default: PyErr_Format(PyExc_ValueError, "Unknown converion specifier %c", @@ -845,7 +797,7 @@ done: } /* - do_markup is the top-level loop for the format() function. It + do_markup is the top-level loop for the format() method. It searches through the format string for escapes to markup codes, and calls other functions to move non-markup text to the output, and to perform the markup to the output. @@ -958,7 +910,7 @@ do_string_format(PyObject *self, PyObject *args, PyObject *kwargs) typedef struct { PyObject_HEAD - PyUnicodeObject *str; + STRINGLIB_OBJECT *str; MarkupIterator it_markup; } formatteriterobject; @@ -984,7 +936,7 @@ formatteriter_next(formatteriterobject *it) SubString literal; SubString field_name; SubString format_spec; - Py_UNICODE conversion; + STRINGLIB_CHAR conversion; int format_spec_needs_expanding; int result = MarkupIterator_next(&it->it_markup, &literal, &field_name, &format_spec, &conversion, @@ -1028,7 +980,7 @@ formatteriter_next(formatteriterobject *it) Py_INCREF(conversion_str); } else - conversion_str = PyUnicode_FromUnicode(&conversion, 1); + conversion_str = STRINGLIB_NEW(&conversion, 1); if (conversion_str == NULL) goto done; @@ -1047,7 +999,7 @@ static PyMethodDef formatteriter_methods[] = { {NULL, NULL} /* sentinel */ }; -PyTypeObject PyFormatterIter_Type = { +static PyTypeObject PyFormatterIter_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "formatteriterator", /* tp_name */ sizeof(formatteriterobject), /* tp_basicsize */ @@ -1085,7 +1037,7 @@ PyTypeObject PyFormatterIter_Type = { describing the parsed elements. It's a wrapper around stringlib/string_format.h's MarkupIterator */ static PyObject * -formatter_parser(PyUnicodeObject *self) +formatter_parser(STRINGLIB_OBJECT *self) { formatteriterobject *it; @@ -1099,8 +1051,8 @@ formatter_parser(PyUnicodeObject *self) /* initialize the contained MarkupIterator */ MarkupIterator_init(&it->it_markup, - PyUnicode_AS_UNICODE(self), - PyUnicode_GET_SIZE(self)); + STRINGLIB_STR(self), + STRINGLIB_LEN(self)); return (PyObject *)it; } @@ -1118,7 +1070,7 @@ formatter_parser(PyUnicodeObject *self) typedef struct { PyObject_HEAD - PyUnicodeObject *str; + STRINGLIB_OBJECT *str; FieldNameIterator it_field; } fieldnameiterobject; @@ -1220,7 +1172,7 @@ static PyTypeObject PyFieldNameIter_Type = { field_name_split. The iterator it returns is a FieldNameIterator */ static PyObject * -formatter_field_name_split(PyUnicodeObject *self) +formatter_field_name_split(STRINGLIB_OBJECT *self) { SubString first; Py_ssize_t first_idx; |