summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/lib/libstdtypes.tex6
-rwxr-xr-xLib/UserString.py1
-rw-r--r--Lib/string.py14
-rw-r--r--Lib/test/string_tests.py10
-rw-r--r--Lib/test/test_unicode.py14
-rw-r--r--Misc/NEWS4
-rw-r--r--Objects/stringobject.c40
-rw-r--r--Objects/unicodeobject.c7
8 files changed, 83 insertions, 13 deletions
diff --git a/Doc/lib/libstdtypes.tex b/Doc/lib/libstdtypes.tex
index 6f819e9..e7275ce 100644
--- a/Doc/lib/libstdtypes.tex
+++ b/Doc/lib/libstdtypes.tex
@@ -694,6 +694,12 @@ must be a string of length 256.
Return a copy of the string converted to uppercase.
\end{methoddesc}
+\begin{methoddesc}[string]{zfill}{width}
+Return the numeric string left filled with zeros in a string
+of length \var{width}. The original string is returned if
+\var{width} is less than \code{len(\var{s})}.
+\end{methoddesc}
+
\subsubsection{String Formatting Operations \label{typesseq-strings}}
diff --git a/Lib/UserString.py b/Lib/UserString.py
index f4f5cab..292e852 100755
--- a/Lib/UserString.py
+++ b/Lib/UserString.py
@@ -128,6 +128,7 @@ class UserString:
def translate(self, *args):
return self.__class__(self.data.translate(*args))
def upper(self): return self.__class__(self.data.upper())
+ def zfill(self, width): return self.__class__(self.data.zfill(width))
class MutableString(UserString):
"""mutable string objects
diff --git a/Lib/string.py b/Lib/string.py
index d68b0bf..cd9909e 100644
--- a/Lib/string.py
+++ b/Lib/string.py
@@ -190,7 +190,10 @@ def rfind(s, *args):
_float = float
_int = int
_long = long
-_StringTypes = (str, unicode)
+try:
+ _StringTypes = (str, unicode)
+except NameError:
+ _StringTypes = (str,)
# Convert string to float
def atof(s):
@@ -277,13 +280,8 @@ def zfill(x, width):
"""
if not isinstance(x, _StringTypes):
- x = str(x)
- n = len(x)
- if n >= width: return x
- sign = ''
- if x[0] in '-+':
- sign, x = x[0], x[1:]
- return sign + '0'*(width-n) + x
+ x = repr(x)
+ return x.zfill(width)
# Expand tabs in a string.
# Doesn't take non-printing chars into account, but does understand \n.
diff --git a/Lib/test/string_tests.py b/Lib/test/string_tests.py
index 5c8dd93..ea25983 100644
--- a/Lib/test/string_tests.py
+++ b/Lib/test/string_tests.py
@@ -227,6 +227,16 @@ def run_method_tests(test):
test('endswith', 'ab', 0, 'ab', 0, 1)
test('endswith', 'ab', 0, 'ab', 0, 0)
+ test('zfill', '123', '123', 2)
+ test('zfill', '123', '123', 3)
+ test('zfill', '123', '0123', 4)
+ test('zfill', '+123', '+123', 3)
+ test('zfill', '+123', '+123', 4)
+ test('zfill', '+123', '+0123', 5)
+ test('zfill', '-123', '-123', 3)
+ test('zfill', '-123', '-123', 4)
+ test('zfill', '-123', '-0123', 5)
+ test('zfill', '', '000', 3)
test('zfill', '34', '34', 1)
test('zfill', '34', '0034', 4)
diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py
index 4b77e75..29dd819 100644
--- a/Lib/test/test_unicode.py
+++ b/Lib/test/test_unicode.py
@@ -206,8 +206,18 @@ if 0:
test('capwords', u'abc\tdef\nghi', u'Abc Def Ghi')
test('capwords', u'abc\t def \nghi', u'Abc Def Ghi')
-verify(string.zfill(u'34', 1) == u'34')
-verify(string.zfill(u'34', 5) == u'00034')
+test('zfill', u'123', u'123', 2)
+test('zfill', u'123', u'123', 3)
+test('zfill', u'123', u'0123', 4)
+test('zfill', u'+123', u'+123', 3)
+test('zfill', u'+123', u'+123', 4)
+test('zfill', u'+123', u'+0123', 5)
+test('zfill', u'-123', u'-123', 3)
+test('zfill', u'-123', u'-123', 4)
+test('zfill', u'-123', u'-0123', 5)
+test('zfill', u'', u'000', 3)
+test('zfill', u'34', u'34', 1)
+test('zfill', u'34', u'00034', 5)
# Comparisons:
print 'Testing Unicode comparisons...',
diff --git a/Misc/NEWS b/Misc/NEWS
index 400b631..a1f5f54 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -6,6 +6,10 @@ Type/class unification and new-style classes
Core and builtins
+- A method zfill() was added to str and unicode, that fills a numeric
+ string to the left with zeros. For example,
+ "+123".zfill(6) -> "+00123".
+
- Complex numbers supported divmod() and the // and % operators, but
these make no sense. Since this was documented, they're being
deprecated now.
diff --git a/Objects/stringobject.c b/Objects/stringobject.c
index 709c5f7..54ccb0d 100644
--- a/Objects/stringobject.c
+++ b/Objects/stringobject.c
@@ -2381,6 +2381,45 @@ string_center(PyStringObject *self, PyObject *args)
return pad(self, left, marg - left, ' ');
}
+static char zfill__doc__[] =
+"S.zfill(width) -> string\n"
+"\n"
+"Pad a numeric string S with zeros on the left, to fill a field\n"
+"of the specified width. The string S is never truncated.";
+
+static PyObject *
+string_zfill(PyStringObject *self, PyObject *args)
+{
+ int fill;
+ PyObject *s;
+ const char *p;
+
+ int width;
+ if (!PyArg_ParseTuple(args, "i:zfill", &width))
+ return NULL;
+
+ if (PyString_GET_SIZE(self) >= width) {
+ Py_INCREF(self);
+ return (PyObject*) self;
+ }
+
+ fill = width - PyString_GET_SIZE(self);
+
+ s = pad(self, fill, 0, '0');
+
+ if (s == NULL)
+ return NULL;
+
+ p = PyString_AS_STRING(s);
+ if (p[fill] == '+' || p[fill] == '-') {
+ /* move sign to beginning of string */
+ p[0] = p[fill];
+ p[fill] = '0';
+ }
+
+ return (PyObject*) s;
+}
+
static char isspace__doc__[] =
"S.isspace() -> bool\n"
"\n"
@@ -2728,6 +2767,7 @@ string_methods[] = {
{"ljust", (PyCFunction)string_ljust, METH_VARARGS, ljust__doc__},
{"rjust", (PyCFunction)string_rjust, METH_VARARGS, rjust__doc__},
{"center", (PyCFunction)string_center, METH_VARARGS, center__doc__},
+ {"zfill", (PyCFunction)string_zfill, METH_VARARGS, zfill__doc__},
{"encode", (PyCFunction)string_encode, METH_VARARGS, encode__doc__},
{"decode", (PyCFunction)string_decode, METH_VARARGS, decode__doc__},
{"expandtabs", (PyCFunction)string_expandtabs, METH_VARARGS, expandtabs__doc__},
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 7d917bd..361612b 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -4824,7 +4824,6 @@ unicode_upper(PyUnicodeObject *self)
return fixup(self, fixupper);
}
-#if 0
static char zfill__doc__[] =
"S.zfill(width) -> unicode\n\
\n\
@@ -4850,6 +4849,9 @@ unicode_zfill(PyUnicodeObject *self, PyObject *args)
u = pad(self, fill, 0, '0');
+ if (u == NULL)
+ return NULL;
+
if (u->str[fill] == '+' || u->str[fill] == '-') {
/* move sign to beginning of string */
u->str[0] = u->str[fill];
@@ -4858,7 +4860,6 @@ unicode_zfill(PyUnicodeObject *self, PyObject *args)
return (PyObject*) u;
}
-#endif
#if 0
static PyObject*
@@ -4970,8 +4971,8 @@ static PyMethodDef unicode_methods[] = {
{"isnumeric", (PyCFunction) unicode_isnumeric, METH_NOARGS, isnumeric__doc__},
{"isalpha", (PyCFunction) unicode_isalpha, METH_NOARGS, isalpha__doc__},
{"isalnum", (PyCFunction) unicode_isalnum, METH_NOARGS, isalnum__doc__},
-#if 0
{"zfill", (PyCFunction) unicode_zfill, METH_VARARGS, zfill__doc__},
+#if 0
{"capwords", (PyCFunction) unicode_capwords, METH_NOARGS, capwords__doc__},
#endif