diff options
author | Eric Smith <eric@trueblade.com> | 2008-05-30 18:10:19 (GMT) |
---|---|---|
committer | Eric Smith <eric@trueblade.com> | 2008-05-30 18:10:19 (GMT) |
commit | 4a7d76ddb51422e2adb0fb56afa5b82162837e52 (patch) | |
tree | 266a1c326d040ce45be22c4c785edec2f7f67f02 /Objects | |
parent | eb2c964aeb0ab0e3e01560c955cab95f8e3b92c2 (diff) | |
download | cpython-4a7d76ddb51422e2adb0fb56afa5b82162837e52.zip cpython-4a7d76ddb51422e2adb0fb56afa5b82162837e52.tar.gz cpython-4a7d76ddb51422e2adb0fb56afa5b82162837e52.tar.bz2 |
Refactor and clean up str.format() code (and helpers) in advance of optimizations.
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/floatobject.c | 13 | ||||
-rw-r--r-- | Objects/longobject.c | 13 | ||||
-rw-r--r-- | Objects/stringlib/formatter.h | 116 | ||||
-rw-r--r-- | Objects/unicodeobject.c | 17 |
4 files changed, 75 insertions, 84 deletions
diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 76a5c2c..dd3ea93 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -7,8 +7,6 @@ #include "Python.h" #include "structseq.h" -#include "formatter_unicode.h" - #include <ctype.h> #include <float.h> @@ -1303,10 +1301,13 @@ float_getzero(PyObject *v, void *closure) static PyObject * float__format__(PyObject *self, PyObject *args) { - /* when back porting this to 2.6, check type of the format_spec - and call either unicode_long__format__ or - string_long__format__ */ - return unicode_float__format__(self, args); + PyObject *format_spec; + + if (!PyArg_ParseTuple(args, "U:__format__", &format_spec)) + return NULL; + return _PyFloat_FormatAdvanced(self, + PyUnicode_AS_UNICODE(format_spec), + PyUnicode_GET_SIZE(format_spec)); } PyDoc_STRVAR(float__format__doc, diff --git a/Objects/longobject.c b/Objects/longobject.c index 08e767e..10d03ae 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -5,8 +5,6 @@ #include "Python.h" #include "longintrepr.h" -#include "formatter_unicode.h" - #include <ctype.h> #ifndef NSMALLPOSINTS @@ -3590,10 +3588,13 @@ long_getN(PyLongObject *v, void *context) { static PyObject * long__format__(PyObject *self, PyObject *args) { - /* when back porting this to 2.6, check type of the format_spec - and call either unicode_long__format__ or - string_long__format__ */ - return unicode_long__format__(self, args); + PyObject *format_spec; + + if (!PyArg_ParseTuple(args, "U:__format__", &format_spec)) + return NULL; + return _PyLong_FormatAdvanced(self, + PyUnicode_AS_UNICODE(format_spec), + PyUnicode_GET_SIZE(format_spec)); } diff --git a/Objects/stringlib/formatter.h b/Objects/stringlib/formatter.h index 05ccfea..2bb2ed2 100644 --- a/Objects/stringlib/formatter.h +++ b/Objects/stringlib/formatter.h @@ -102,12 +102,13 @@ typedef struct { if failure, sets the exception */ static int -parse_internal_render_format_spec(PyObject *format_spec, +parse_internal_render_format_spec(STRINGLIB_CHAR *format_spec, + Py_ssize_t format_spec_len, InternalFormatSpec *format, char default_type) { - STRINGLIB_CHAR *ptr = STRINGLIB_STR(format_spec); - STRINGLIB_CHAR *end = ptr + STRINGLIB_LEN(format_spec); + STRINGLIB_CHAR *ptr = format_spec; + STRINGLIB_CHAR *end = format_spec + format_spec_len; /* end-ptr is used throughout this code to specify the length of the input string */ @@ -756,56 +757,31 @@ done: /************************************************************************/ /*********** built in formatters ****************************************/ /************************************************************************/ -#ifdef FORMAT_STRING PyObject * -FORMAT_STRING(PyObject* value, PyObject* args) +FORMAT_STRING(PyObject *obj, + STRINGLIB_CHAR *format_spec, + Py_ssize_t format_spec_len) { - PyObject *format_spec; - PyObject *result = NULL; -#if PY_VERSION_HEX < 0x03000000 - PyObject *tmp = NULL; -#endif InternalFormatSpec format; - - /* If 2.x, we accept either str or unicode, and try to convert it - to the right type. In 3.x, we insist on only unicode */ -#if PY_VERSION_HEX >= 0x03000000 - if (!PyArg_ParseTuple(args, STRINGLIB_PARSE_CODE ":__format__", - &format_spec)) - goto done; -#else - /* If 2.x, convert format_spec to the same type as value */ - /* This is to allow things like u''.format('') */ - if (!PyArg_ParseTuple(args, "O:__format__", &format_spec)) - goto done; - if (!(PyBytes_Check(format_spec) || PyUnicode_Check(format_spec))) { - PyErr_Format(PyExc_TypeError, "__format__ arg must be str " - "or unicode, not %s", Py_TYPE(format_spec)->tp_name); - goto done; - } - tmp = STRINGLIB_TOSTR(format_spec); - if (tmp == NULL) - goto done; - format_spec = tmp; -#endif + PyObject *result = NULL; /* check for the special case of zero length format spec, make - it equivalent to str(value) */ - if (STRINGLIB_LEN(format_spec) == 0) { - result = STRINGLIB_TOSTR(value); + it equivalent to str(obj) */ + if (format_spec_len == 0) { + result = STRINGLIB_TOSTR(obj); goto done; } - /* parse the format_spec */ - if (!parse_internal_render_format_spec(format_spec, &format, 's')) + if (!parse_internal_render_format_spec(format_spec, format_spec_len, + &format, 's')) goto done; /* type conversion? */ switch (format.type) { case 's': /* no type conversion needed, already a string. do the formatting */ - result = format_string_internal(value, &format); + result = format_string_internal(obj, &format); break; default: /* unknown */ @@ -826,35 +802,31 @@ FORMAT_STRING(PyObject* value, PyObject* args) } done: -#if PY_VERSION_HEX < 0x03000000 - Py_XDECREF(tmp); -#endif return result; } -#endif /* FORMAT_STRING */ #if defined FORMAT_LONG || defined FORMAT_INT static PyObject* -format_int_or_long(PyObject* value, PyObject* args, IntOrLongToString tostring) +format_int_or_long(PyObject* obj, + STRINGLIB_CHAR *format_spec, + Py_ssize_t format_spec_len, + IntOrLongToString tostring) { - PyObject *format_spec; PyObject *result = NULL; PyObject *tmp = NULL; InternalFormatSpec format; - if (!PyArg_ParseTuple(args, STRINGLIB_PARSE_CODE ":__format__", - &format_spec)) - goto done; - /* check for the special case of zero length format spec, make - it equivalent to str(value) */ - if (STRINGLIB_LEN(format_spec) == 0) { - result = STRINGLIB_TOSTR(value); + it equivalent to str(obj) */ + if (format_spec_len == 0) { + result = STRINGLIB_TOSTR(obj); goto done; } /* parse the format_spec */ - if (!parse_internal_render_format_spec(format_spec, &format, 'd')) + if (!parse_internal_render_format_spec(format_spec, + format_spec_len, + &format, 'd')) goto done; /* type conversion? */ @@ -868,7 +840,7 @@ format_int_or_long(PyObject* value, PyObject* args, IntOrLongToString tostring) case 'n': /* no type conversion needed, already an int (or long). do the formatting */ - result = format_int_or_long_internal(value, &format, tostring); + result = format_int_or_long_internal(obj, &format, tostring); break; case 'e': @@ -879,10 +851,10 @@ format_int_or_long(PyObject* value, PyObject* args, IntOrLongToString tostring) case 'G': case '%': /* convert to float */ - tmp = PyNumber_Float(value); + tmp = PyNumber_Float(obj); if (tmp == NULL) goto done; - result = format_float_internal(value, &format); + result = format_float_internal(obj, &format); break; default: @@ -917,9 +889,12 @@ long_format(PyObject* value, int base) #endif PyObject * -FORMAT_LONG(PyObject* value, PyObject* args) +FORMAT_LONG(PyObject *obj, + STRINGLIB_CHAR *format_spec, + Py_ssize_t format_spec_len) { - return format_int_or_long(value, args, long_format); + return format_int_or_long(obj, format_spec, format_spec_len, + long_format); } #endif /* FORMAT_LONG */ @@ -935,32 +910,35 @@ int_format(PyObject* value, int base) } PyObject * -FORMAT_INT(PyObject* value, PyObject* args) +FORMAT_INT(PyObject *obj, + STRINGLIB_CHAR *format_spec, + Py_ssize_t format_spec_len) { - return format_int_or_long(value, args, int_format); + return format_int_or_long(obj, format_spec, format_spec_len, + int_format); } #endif /* FORMAT_INT */ #ifdef FORMAT_FLOAT PyObject * -FORMAT_FLOAT(PyObject *value, PyObject *args) +FORMAT_FLOAT(PyObject *obj, + STRINGLIB_CHAR *format_spec, + Py_ssize_t format_spec_len) { - PyObject *format_spec; PyObject *result = NULL; InternalFormatSpec format; - if (!PyArg_ParseTuple(args, STRINGLIB_PARSE_CODE ":__format__", &format_spec)) - goto done; - /* check for the special case of zero length format spec, make - it equivalent to str(value) */ - if (STRINGLIB_LEN(format_spec) == 0) { - result = STRINGLIB_TOSTR(value); + it equivalent to str(obj) */ + if (format_spec_len == 0) { + result = STRINGLIB_TOSTR(obj); goto done; } /* parse the format_spec */ - if (!parse_internal_render_format_spec(format_spec, &format, '\0')) + if (!parse_internal_render_format_spec(format_spec, + format_spec_len, + &format, '\0')) goto done; /* type conversion? */ @@ -979,7 +957,7 @@ FORMAT_FLOAT(PyObject *value, PyObject *args) case 'n': case '%': /* no conversion, already a float. do the formatting */ - result = format_float_internal(value, &format); + result = format_float_internal(obj, &format); break; default: diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index ca51b0c..78e38b5 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -46,8 +46,6 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "unicodeobject.h" #include "ucnhash.h" -#include "formatter_unicode.h" - #ifdef MS_WINDOWS #include <windows.h> #endif @@ -8202,6 +8200,19 @@ PyDoc_STRVAR(format__doc__, \n\ "); +static PyObject * +unicode__format__(PyObject* self, PyObject* args) +{ + PyObject *format_spec; + + if (!PyArg_ParseTuple(args, "U:__format__", &format_spec)) + return NULL; + + return _PyUnicode_FormatAdvanced(self, + PyUnicode_AS_UNICODE(format_spec), + PyUnicode_GET_SIZE(format_spec)); +} + PyDoc_STRVAR(p_format__doc__, "S.__format__(format_spec) -> str\n\ \n\ @@ -8259,7 +8270,7 @@ static PyMethodDef unicode_methods[] = { {"isidentifier", (PyCFunction) unicode_isidentifier, METH_NOARGS, isidentifier__doc__}, {"zfill", (PyCFunction) unicode_zfill, METH_VARARGS, zfill__doc__}, {"format", (PyCFunction) do_string_format, METH_VARARGS | METH_KEYWORDS, format__doc__}, - {"__format__", (PyCFunction) unicode_unicode__format__, METH_VARARGS, p_format__doc__}, + {"__format__", (PyCFunction) unicode__format__, METH_VARARGS, p_format__doc__}, {"_formatter_field_name_split", (PyCFunction) formatter_field_name_split, METH_NOARGS}, {"_formatter_parser", (PyCFunction) formatter_parser, METH_NOARGS}, {"maketrans", (PyCFunction) unicode_maketrans, |