Skip to content

Commit cf6b910

Browse files
author
eric.smith
committed
Refactor and clean up str.format() code (and helpers) in advance of optimizations.
git-svn-id: http://svn.python.org/projects/python/trunk@63814 6015fed2-1504-0410-9fe1-9d1591cc4771
1 parent 005cf24 commit cf6b910

File tree

15 files changed

+176
-157
lines changed

15 files changed

+176
-157
lines changed

Include/bytesobject.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,12 @@ PyAPI_FUNC(int) _PyBytes_InsertThousandsGrouping(char *buffer,
188188
Py_ssize_t *count,
189189
int append_zero_char);
190190

191+
/* Format the object based on the format_spec, as defined in PEP 3101
192+
(Advanced String Formatting). */
193+
PyAPI_FUNC(PyObject *) _PyBytes_FormatAdvanced(PyObject *obj,
194+
char *format_spec,
195+
Py_ssize_t format_spec_len);
196+
191197
#ifdef __cplusplus
192198
}
193199
#endif

Include/floatobject.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,12 @@ PyAPI_FUNC(double) _PyFloat_Unpack8(const unsigned char *p, int le);
115115
/* free list api */
116116
PyAPI_FUNC(void) PyFloat_CompactFreeList(size_t *, size_t *, size_t *);
117117

118+
/* Format the object based on the format_spec, as defined in PEP 3101
119+
(Advanced String Formatting). */
120+
PyAPI_FUNC(PyObject *) _PyFloat_FormatAdvanced(PyObject *obj,
121+
char *format_spec,
122+
Py_ssize_t format_spec_len);
123+
118124
#ifdef __cplusplus
119125
}
120126
#endif

Include/formatter_string.h

Lines changed: 0 additions & 12 deletions
This file was deleted.

Include/formatter_unicode.h

Lines changed: 0 additions & 12 deletions
This file was deleted.

Include/intobject.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,12 @@ PyAPI_FUNC(void) PyInt_CompactFreeList(size_t *, size_t *, size_t *);
6868
a leading "0" */
6969
PyAPI_FUNC(PyObject*) _PyInt_Format(PyIntObject* v, int base, int newstyle);
7070

71+
/* Format the object based on the format_spec, as defined in PEP 3101
72+
(Advanced String Formatting). */
73+
PyAPI_FUNC(PyObject *) _PyInt_FormatAdvanced(PyObject *obj,
74+
char *format_spec,
75+
Py_ssize_t format_spec_len);
76+
7177
#ifdef __cplusplus
7278
}
7379
#endif

Include/longobject.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,12 @@ PyAPI_FUNC(int) _PyLong_AsByteArray(PyLongObject* v,
119119
a leading "0", instead of the prefix "0o" */
120120
PyAPI_FUNC(PyObject *) _PyLong_Format(PyObject *aa, int base, int addL, int newstyle);
121121

122+
/* Format the object based on the format_spec, as defined in PEP 3101
123+
(Advanced String Formatting). */
124+
PyAPI_FUNC(PyObject *) _PyLong_FormatAdvanced(PyObject *obj,
125+
char *format_spec,
126+
Py_ssize_t format_spec_len);
127+
122128
#ifdef __cplusplus
123129
}
124130
#endif

Include/unicodeobject.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,12 @@ PyAPI_FUNC(PyObject*) PyUnicode_FromObject(
553553
PyAPI_FUNC(PyObject *) PyUnicode_FromFormatV(const char*, va_list);
554554
PyAPI_FUNC(PyObject *) PyUnicode_FromFormat(const char*, ...);
555555

556+
/* Format the object based on the format_spec, as defined in PEP 3101
557+
(Advanced String Formatting). */
558+
PyAPI_FUNC(PyObject *) _PyUnicode_FormatAdvanced(PyObject *obj,
559+
Py_UNICODE *format_spec,
560+
Py_ssize_t format_spec_len);
561+
556562
/* --- wchar_t support for platforms which support it --------------------- */
557563

558564
#ifdef HAVE_WCHAR_H

Objects/bytesobject.c

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@
33
#define PY_SSIZE_T_CLEAN
44

55
#include "Python.h"
6-
7-
#include "formatter_string.h"
8-
96
#include <ctype.h>
107

118
#ifdef COUNT_ALLOCS
@@ -3939,6 +3936,35 @@ PyDoc_STRVAR(format__doc__,
39393936
\n\
39403937
");
39413938

3939+
static PyObject *
3940+
string__format__(PyObject* self, PyObject* args)
3941+
{
3942+
PyObject *format_spec;
3943+
PyObject *result = NULL;
3944+
PyObject *tmp = NULL;
3945+
3946+
/* If 2.x, convert format_spec to the same type as value */
3947+
/* This is to allow things like u''.format('') */
3948+
if (!PyArg_ParseTuple(args, "O:__format__", &format_spec))
3949+
goto done;
3950+
if (!(PyBytes_Check(format_spec) || PyUnicode_Check(format_spec))) {
3951+
PyErr_Format(PyExc_TypeError, "__format__ arg must be str "
3952+
"or unicode, not %s", Py_TYPE(format_spec)->tp_name);
3953+
goto done;
3954+
}
3955+
tmp = PyObject_Str(format_spec);
3956+
if (tmp == NULL)
3957+
goto done;
3958+
format_spec = tmp;
3959+
3960+
result = _PyBytes_FormatAdvanced(self,
3961+
PyBytes_AS_STRING(format_spec),
3962+
PyBytes_GET_SIZE(format_spec));
3963+
done:
3964+
Py_XDECREF(tmp);
3965+
return result;
3966+
}
3967+
39423968
PyDoc_STRVAR(p_format__doc__,
39433969
"S.__format__(format_spec) -> unicode\n\
39443970
\n\

Objects/floatobject.c

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,6 @@
1414
#include <ieeefp.h>
1515
#endif
1616

17-
#include "formatter_string.h"
18-
19-
2017
#ifdef _OSF_SOURCE
2118
/* OSF1 5.1 doesn't make this available with XOPEN_SOURCE_EXTENDED defined */
2219
extern int finite(double);
@@ -1398,26 +1395,22 @@ float__format__(PyObject *self, PyObject *args)
13981395
if (!PyArg_ParseTuple(args, "O:__format__", &format_spec))
13991396
return NULL;
14001397
if (PyBytes_Check(format_spec))
1401-
return string_float__format__(self, args);
1398+
return _PyFloat_FormatAdvanced(self,
1399+
PyBytes_AS_STRING(format_spec),
1400+
PyBytes_GET_SIZE(format_spec));
14021401
if (PyUnicode_Check(format_spec)) {
14031402
/* Convert format_spec to a str */
1404-
PyObject *result = NULL;
1405-
PyObject *newargs = NULL;
1406-
PyObject *string_format_spec = NULL;
1403+
PyObject *result;
1404+
PyObject *str_spec = PyObject_Str(format_spec);
14071405

1408-
string_format_spec = PyObject_Str(format_spec);
1409-
if (string_format_spec == NULL)
1410-
goto done;
1411-
1412-
newargs = Py_BuildValue("(O)", string_format_spec);
1413-
if (newargs == NULL)
1414-
goto done;
1406+
if (str_spec == NULL)
1407+
return NULL;
14151408

1416-
result = string_float__format__(self, newargs);
1409+
result = _PyFloat_FormatAdvanced(self,
1410+
PyBytes_AS_STRING(str_spec),
1411+
PyBytes_GET_SIZE(str_spec));
14171412

1418-
done:
1419-
Py_XDECREF(string_format_spec);
1420-
Py_XDECREF(newargs);
1413+
Py_DECREF(str_spec);
14211414
return result;
14221415
}
14231416
PyErr_SetString(PyExc_TypeError, "__format__ requires str or unicode");

Objects/intobject.c

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
#include "Python.h"
55
#include <ctype.h>
6-
#include "formatter_string.h"
76

87
static PyObject *int_int(PyIntObject *v);
98

@@ -1117,26 +1116,22 @@ int__format__(PyObject *self, PyObject *args)
11171116
if (!PyArg_ParseTuple(args, "O:__format__", &format_spec))
11181117
return NULL;
11191118
if (PyBytes_Check(format_spec))
1120-
return string_int__format__(self, args);
1119+
return _PyInt_FormatAdvanced(self,
1120+
PyBytes_AS_STRING(format_spec),
1121+
PyBytes_GET_SIZE(format_spec));
11211122
if (PyUnicode_Check(format_spec)) {
11221123
/* Convert format_spec to a str */
1123-
PyObject *result = NULL;
1124-
PyObject *newargs = NULL;
1125-
PyObject *string_format_spec = NULL;
1124+
PyObject *result;
1125+
PyObject *str_spec = PyObject_Str(format_spec);
11261126

1127-
string_format_spec = PyObject_Str(format_spec);
1128-
if (string_format_spec == NULL)
1129-
goto done;
1130-
1131-
newargs = Py_BuildValue("(O)", string_format_spec);
1132-
if (newargs == NULL)
1133-
goto done;
1127+
if (str_spec == NULL)
1128+
return NULL;
11341129

1135-
result = string_int__format__(self, newargs);
1130+
result = _PyInt_FormatAdvanced(self,
1131+
PyBytes_AS_STRING(str_spec),
1132+
PyBytes_GET_SIZE(str_spec));
11361133

1137-
done:
1138-
Py_XDECREF(string_format_spec);
1139-
Py_XDECREF(newargs);
1134+
Py_DECREF(str_spec);
11401135
return result;
11411136
}
11421137
PyErr_SetString(PyExc_TypeError, "__format__ requires str or unicode");

0 commit comments

Comments
 (0)