]> granicus.if.org Git - python/commitdiff
Add optional fillchar argument to ljust(), rjust(), and center() string methods.
authorRaymond Hettinger <python@rcn.com>
Wed, 26 Nov 2003 08:21:35 +0000 (08:21 +0000)
committerRaymond Hettinger <python@rcn.com>
Wed, 26 Nov 2003 08:21:35 +0000 (08:21 +0000)
Doc/lib/libstdtypes.tex
Lib/UserString.py
Lib/string.py
Lib/test/string_tests.py
Misc/NEWS
Objects/stringobject.c
Objects/unicodeobject.c

index 4eb45958597ee2e87619ad37312d1d63e70910df..9281dac8a3c47f60b7ced54dfed34a0d051c69b0 100644 (file)
@@ -546,9 +546,9 @@ objects support:
 Return a copy of the string with only its first character capitalized.
 \end{methoddesc}
 
-\begin{methoddesc}[string]{center}{width}
+\begin{methoddesc}[string]{center}{width\optional{, fillchar}}
 Return centered in a string of length \var{width}. Padding is done
-using spaces.
+using the specified \var{fillchar} (default is a space).
 \end{methoddesc}
 
 \begin{methoddesc}[string]{count}{sub\optional{, start\optional{, end}}}
@@ -645,9 +645,10 @@ sequence \var{seq}.  The separator between elements is the string
 providing this method.
 \end{methoddesc}
 
-\begin{methoddesc}[string]{ljust}{width}
+\begin{methoddesc}[string]{ljust}{width\optional{, fillchar}}
 Return the string left justified in a string of length \var{width}.
-Padding is done using spaces.  The original string is returned if
+Padding is done using the specified \var{fillchar} (default is a
+space).  The original string is returned if
 \var{width} is less than \code{len(\var{s})}.
 \end{methoddesc}
 
@@ -683,9 +684,10 @@ Like \method{rfind()} but raises \exception{ValueError} when the
 substring \var{sub} is not found.
 \end{methoddesc}
 
-\begin{methoddesc}[string]{rjust}{width}
+\begin{methoddesc}[string]{rjust}{width\optional{, fillchar}}
 Return the string right justified in a string of length \var{width}.
-Padding is done using spaces.  The original string is returned if
+Padding is done using the specified \var{fillchar} (default is a space).
+The original string is returned if
 \var{width} is less than \code{len(\var{s})}.
 \end{methoddesc}
 
index 730cdba9e305c2f47533c2d7faca98cf6f7da590..f28e54c44102226d4c9d9c70b97bfcbfcb12e0c1 100755 (executable)
@@ -60,7 +60,8 @@ class UserString:
 
     # the following methods are defined in alphabetical order:
     def capitalize(self): return self.__class__(self.data.capitalize())
-    def center(self, width): return self.__class__(self.data.center(width))
+    def center(self, width, *args):
+        return self.__class__(self.data.center(width, *args))
     def count(self, sub, start=0, end=sys.maxint):
         return self.data.count(sub, start, end)
     def decode(self, encoding=None, errors=None): # XXX improve this?
@@ -97,7 +98,8 @@ class UserString:
     def istitle(self): return self.data.istitle()
     def isupper(self): return self.data.isupper()
     def join(self, seq): return self.data.join(seq)
-    def ljust(self, width): return self.__class__(self.data.ljust(width))
+    def ljust(self, width, *args):
+        return self.__class__(self.data.ljust(width, *args))
     def lower(self): return self.__class__(self.data.lower())
     def lstrip(self, chars=None): return self.__class__(self.data.lstrip(chars))
     def replace(self, old, new, maxsplit=-1):
@@ -106,7 +108,8 @@ class UserString:
         return self.data.rfind(sub, start, end)
     def rindex(self, sub, start=0, end=sys.maxint):
         return self.data.rindex(sub, start, end)
-    def rjust(self, width): return self.__class__(self.data.rjust(width))
+    def rjust(self, width, *args):
+        return self.__class__(self.data.rjust(width, *args))
     def rstrip(self, chars=None): return self.__class__(self.data.rstrip(chars))
     def split(self, sep=None, maxsplit=-1):
         return self.data.split(sep, maxsplit)
index 5b5ddc3bb558cf8e7d31938a2691e41bc5c9b773..0a77f461ffda09b4ddf9e0cb2c45414b91f6d225 100644 (file)
@@ -237,37 +237,37 @@ def atol(s, base=10):
 
 
 # Left-justify a string
-def ljust(s, width):
-    """ljust(s, width) -> string
+def ljust(s, width, *args):
+    """ljust(s, width[, fillchar]) -> string
 
     Return a left-justified version of s, in a field of the
     specified width, padded with spaces as needed.  The string is
-    never truncated.
+    never truncated.  If specified the fillchar is used instead of spaces.
 
     """
-    return s.ljust(width)
+    return s.ljust(width, *args)
 
 # Right-justify a string
-def rjust(s, width):
-    """rjust(s, width) -> string
+def rjust(s, width, *args):
+    """rjust(s, width[, fillchar]) -> string
 
     Return a right-justified version of s, in a field of the
     specified width, padded with spaces as needed.  The string is
-    never truncated.
+    never truncated.  If specified the fillchar is used instead of spaces.
 
     """
-    return s.rjust(width)
+    return s.rjust(width, *args)
 
 # Center a string
-def center(s, width):
-    """center(s, width) -> string
+def center(s, width, *args):
+    """center(s, width[, fillchar]) -> string
 
     Return a center version of s, in a field of the specified
     width. padded with spaces as needed.  The string is never
-    truncated.
+    truncated.  If specified the fillchar is used instead of spaces.
 
     """
-    return s.center(width)
+    return s.center(width, *args)
 
 # Zero-fill a number, e.g., (12, 3) --> '012' and (-3, 3) --> '-03'
 # Decadent feature: the argument may be a string or a number
index af171d08ab3fc6e49c1449b65f6c1beebb4cad90..236c577607cd11080fd71ff73fc9f2afe22182f3 100644 (file)
@@ -227,7 +227,7 @@ class CommonTest(unittest.TestCase):
         self.checkequal('abc   ', 'abc', 'ljust', 6)
         self.checkequal('abc', 'abc', 'ljust', 3)
         self.checkequal('abc', 'abc', 'ljust', 2)
-
+        self.checkequal('abc*******', 'abc', 'ljust', 10, '*')
         self.checkraises(TypeError, 'abc', 'ljust')
 
     def test_rjust(self):
@@ -235,7 +235,7 @@ class CommonTest(unittest.TestCase):
         self.checkequal('   abc', 'abc', 'rjust', 6)
         self.checkequal('abc', 'abc', 'rjust', 3)
         self.checkequal('abc', 'abc', 'rjust', 2)
-
+        self.checkequal('*******abc', 'abc', 'rjust', 10, '*')
         self.checkraises(TypeError, 'abc', 'rjust')
 
     def test_center(self):
@@ -243,7 +243,7 @@ class CommonTest(unittest.TestCase):
         self.checkequal(' abc  ', 'abc', 'center', 6)
         self.checkequal('abc', 'abc', 'center', 3)
         self.checkequal('abc', 'abc', 'center', 2)
-
+        self.checkequal('***abc****', 'abc', 'center', 10, '*')
         self.checkraises(TypeError, 'abc', 'center')
 
     def test_swapcase(self):
index a3f3a18969ffafc9f2399a8cfd5418bc0e1a0ca9..c9b7baa1c69cf4de4a1ae9d6197256bec28e2580 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,10 @@ What's New in Python 2.4 alpha 1?
 Core and builtins
 -----------------
 
+- For str and unicode objects, the ljust(), center(), and rjust()
+  methods now accept an optional argument specifying a fill
+  character other than a space.
+
 - When method objects have an attribute that can be satisfied either
   by the function object or by the method object, the function
   object's attribute usually wins.  Christian Tismer pointed out that
index 0a224406710251e02e4439ec32aa1e93e8143826..739cc3edded2d66b3f258258de6a039651208c4b 100644 (file)
@@ -2617,16 +2617,18 @@ pad(PyStringObject *self, int left, int right, char fill)
 }
 
 PyDoc_STRVAR(ljust__doc__,
-"S.ljust(width) -> string\n"
+"S.ljust(width[, fillchar]) -> string\n"
 "\n"
 "Return S left justified in a string of length width. Padding is\n"
-"done using spaces.");
+"done using the specified fill character (default is a space).");
 
 static PyObject *
 string_ljust(PyStringObject *self, PyObject *args)
 {
     int width;
-    if (!PyArg_ParseTuple(args, "i:ljust", &width))
+    char fillchar = ' ';
+
+    if (!PyArg_ParseTuple(args, "i|c:ljust", &width, &fillchar))
         return NULL;
 
     if (PyString_GET_SIZE(self) >= width && PyString_CheckExact(self)) {
@@ -2634,21 +2636,23 @@ string_ljust(PyStringObject *self, PyObject *args)
         return (PyObject*) self;
     }
 
-    return pad(self, 0, width - PyString_GET_SIZE(self), ' ');
+    return pad(self, 0, width - PyString_GET_SIZE(self), fillchar);
 }
 
 
 PyDoc_STRVAR(rjust__doc__,
-"S.rjust(width) -> string\n"
+"S.rjust(width[, fillchar]) -> string\n"
 "\n"
 "Return S right justified in a string of length width. Padding is\n"
-"done using spaces.");
+"done using the specified fill character (default is a space)");
 
 static PyObject *
 string_rjust(PyStringObject *self, PyObject *args)
 {
     int width;
-    if (!PyArg_ParseTuple(args, "i:rjust", &width))
+    char fillchar = ' ';
+
+    if (!PyArg_ParseTuple(args, "i|c:rjust", &width, &fillchar))
         return NULL;
 
     if (PyString_GET_SIZE(self) >= width && PyString_CheckExact(self)) {
@@ -2656,23 +2660,24 @@ string_rjust(PyStringObject *self, PyObject *args)
         return (PyObject*) self;
     }
 
-    return pad(self, width - PyString_GET_SIZE(self), 0, ' ');
+    return pad(self, width - PyString_GET_SIZE(self), 0, fillchar);
 }
 
 
 PyDoc_STRVAR(center__doc__,
-"S.center(width) -> string\n"
+"S.center(width[, fillchar]) -> string\n"
 "\n"
-"Return S centered in a string of length width. Padding is done\n"
-"using spaces.");
+"Return S centered in a string of length width. Padding is\n"
+"done using the specified fill character (default is a space)");
 
 static PyObject *
 string_center(PyStringObject *self, PyObject *args)
 {
     int marg, left;
     int width;
+    char fillchar = ' ';
 
-    if (!PyArg_ParseTuple(args, "i:center", &width))
+    if (!PyArg_ParseTuple(args, "i|c:center", &width, &fillchar))
         return NULL;
 
     if (PyString_GET_SIZE(self) >= width && PyString_CheckExact(self)) {
@@ -2683,7 +2688,7 @@ string_center(PyStringObject *self, PyObject *args)
     marg = width - PyString_GET_SIZE(self);
     left = marg / 2 + (marg & width & 1);
 
-    return pad(self, left, marg - left, ' ');
+    return pad(self, left, marg - left, fillchar);
 }
 
 PyDoc_STRVAR(zfill__doc__,
index e4fe53169567c7711e79e560de3092b6ea219bc5..c950f8b1691c712c4385ec78cd71770cc1ccabd4 100644 (file)
@@ -4404,19 +4404,47 @@ onError:
 }
 #endif
 
+/* Argument converter.  Coerces to a single unicode character */
+
+static int
+convert_uc(PyObject *obj, void *addr)
+{
+       Py_UNICODE *fillcharloc = (Py_UNICODE *)addr;
+       PyObject *uniobj;
+       Py_UNICODE *unistr;
+
+       uniobj = PyUnicode_FromObject(obj);
+       if (uniobj == NULL) {
+               PyErr_SetString(PyExc_TypeError,
+                       "The fill character cannot be converted to Unicode");
+               return 0;
+       }
+       if (PyUnicode_GET_SIZE(uniobj) != 1) {
+               PyErr_SetString(PyExc_TypeError,
+                       "The fill character must be exactly one character long");
+               Py_DECREF(uniobj);
+               return 0;
+       }
+       unistr = PyUnicode_AS_UNICODE(uniobj);
+       *fillcharloc = unistr[0];
+       Py_DECREF(uniobj);
+       return 1;
+}
+
 PyDoc_STRVAR(center__doc__,
-"S.center(width) -> unicode\n\
+"S.center(width[, fillchar]) -> unicode\n\
 \n\
-Return S centered in a Unicode string of length width. Padding is done\n\
-using spaces.");
+Return S centered in a Unicode string of length width. Padding is\n\
+done using the specified fill character (default is a space)");
 
 static PyObject *
 unicode_center(PyUnicodeObject *self, PyObject *args)
 {
     int marg, left;
     int width;
+    Py_UNICODE fillchar = ' ';
 
-    if (!PyArg_ParseTuple(args, "i:center", &width))
+    if (!PyArg_ParseTuple(args, "i|O&:center", &width, convert_uc, &fillchar))
         return NULL;
 
     if (self->length >= width && PyUnicode_CheckExact(self)) {
@@ -4427,7 +4455,7 @@ unicode_center(PyUnicodeObject *self, PyObject *args)
     marg = width - self->length;
     left = marg / 2 + (marg & width & 1);
 
-    return (PyObject*) pad(self, left, marg - left, ' ');
+    return (PyObject*) pad(self, left, marg - left, fillchar);
 }
 
 #if 0
@@ -5170,16 +5198,18 @@ unicode_length(PyUnicodeObject *self)
 }
 
 PyDoc_STRVAR(ljust__doc__,
-"S.ljust(width) -> unicode\n\
+"S.ljust(width[, fillchar]) -> unicode\n\
 \n\
 Return S left justified in a Unicode string of length width. Padding is\n\
-done using spaces.");
+done using the specified fill character (default is a space).");
 
 static PyObject *
 unicode_ljust(PyUnicodeObject *self, PyObject *args)
 {
     int width;
-    if (!PyArg_ParseTuple(args, "i:ljust", &width))
+    Py_UNICODE fillchar = ' ';
+
+    if (!PyArg_ParseTuple(args, "i|O&:ljust", &width, convert_uc, &fillchar))
         return NULL;
 
     if (self->length >= width && PyUnicode_CheckExact(self)) {
@@ -5187,7 +5217,7 @@ unicode_ljust(PyUnicodeObject *self, PyObject *args)
         return (PyObject*) self;
     }
 
-    return (PyObject*) pad(self, 0, width - self->length, ' ');
+    return (PyObject*) pad(self, 0, width - self->length, fillchar);
 }
 
 PyDoc_STRVAR(lower__doc__,
@@ -5552,16 +5582,18 @@ unicode_rindex(PyUnicodeObject *self, PyObject *args)
 }
 
 PyDoc_STRVAR(rjust__doc__,
-"S.rjust(width) -> unicode\n\
+"S.rjust(width[, fillchar]) -> unicode\n\
 \n\
 Return S right justified in a Unicode string of length width. Padding is\n\
-done using spaces.");
+done using the specified fill character (default is a space).");
 
 static PyObject *
 unicode_rjust(PyUnicodeObject *self, PyObject *args)
 {
     int width;
-    if (!PyArg_ParseTuple(args, "i:rjust", &width))
+    Py_UNICODE fillchar = ' ';
+
+    if (!PyArg_ParseTuple(args, "i|O&:rjust", &width, convert_uc, &fillchar))
         return NULL;
 
     if (self->length >= width && PyUnicode_CheckExact(self)) {
@@ -5569,7 +5601,7 @@ unicode_rjust(PyUnicodeObject *self, PyObject *args)
         return (PyObject*) self;
     }
 
-    return (PyObject*) pad(self, width - self->length, 0, ' ');
+    return (PyObject*) pad(self, width - self->length, 0, fillchar);
 }
 
 static PyObject*