diff options
-rw-r--r-- | Doc/lib/libstdtypes.tex | 6 | ||||
-rwxr-xr-x | Lib/UserString.py | 1 | ||||
-rw-r--r-- | Lib/string.py | 14 | ||||
-rw-r--r-- | Lib/test/string_tests.py | 10 | ||||
-rw-r--r-- | Lib/test/test_unicode.py | 14 | ||||
-rw-r--r-- | Misc/NEWS | 4 | ||||
-rw-r--r-- | Objects/stringobject.c | 40 | ||||
-rw-r--r-- | Objects/unicodeobject.c | 7 |
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...', @@ -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 |