aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Objects/stringlib/string_format.h
diff options
context:
space:
mode:
authorEric Smith <eric@trueblade.com>2008-02-17 19:48:00 +0000
committerEric Smith <eric@trueblade.com>2008-02-17 19:48:00 +0000
commit8fd3eba0501a77eec463179f529f56025ff4b40b (patch)
treed459220bd52a30ce3de89b89ed1db077e7b5d4a4 /Objects/stringlib/string_format.h
parent18c66898b0a14761786161c07d89d65c8f088601 (diff)
downloadcpython-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.h96
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;