summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaymond Hettinger <python@rcn.com>2003-11-26 08:21:35 (GMT)
committerRaymond Hettinger <python@rcn.com>2003-11-26 08:21:35 (GMT)
commit4f8f9765766a126ebfff3c81655454821f1ad532 (patch)
tree90f6c08e42a551b8bb461d191afddaef5e4f0cf4
parentbd93b3ea8fd87742dd56c9c1ff514223892e0d4a (diff)
downloadcpython-4f8f9765766a126ebfff3c81655454821f1ad532.zip
cpython-4f8f9765766a126ebfff3c81655454821f1ad532.tar.gz
cpython-4f8f9765766a126ebfff3c81655454821f1ad532.tar.bz2
Add optional fillchar argument to ljust(), rjust(), and center() string methods.
-rw-r--r--Doc/lib/libstdtypes.tex14
-rwxr-xr-xLib/UserString.py9
-rw-r--r--Lib/string.py24
-rw-r--r--Lib/test/string_tests.py6
-rw-r--r--Misc/NEWS4
-rw-r--r--Objects/stringobject.c31
-rw-r--r--Objects/unicodeobject.c58
7 files changed, 96 insertions, 50 deletions
diff --git a/Doc/lib/libstdtypes.tex b/Doc/lib/libstdtypes.tex
index 4eb4595..9281dac 100644
--- a/Doc/lib/libstdtypes.tex
+++ b/Doc/lib/libstdtypes.tex
@@ -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}
diff --git a/Lib/UserString.py b/Lib/UserString.py
index 730cdba..f28e54c 100755
--- a/Lib/UserString.py
+++ b/Lib/UserString.py
@@ -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)
diff --git a/Lib/string.py b/Lib/string.py
index 5b5ddc3..0a77f46 100644
--- a/Lib/string.py
+++ b/Lib/string.py
@@ -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
diff --git a/Lib/test/string_tests.py b/Lib/test/string_tests.py
index af171d0..236c577 100644
--- a/Lib/test/string_tests.py
+++ b/Lib/test/string_tests.py
@@ -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):
diff --git a/Misc/NEWS b/Misc/NEWS
index a3f3a18..c9b7baa 100644
--- 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
diff --git a/Objects/stringobject.c b/Objects/stringobject.c
index 0a22440..739cc3e 100644
--- a/Objects/stringobject.c
+++ b/Objects/stringobject.c
@@ -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__,
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index e4fe531..c950f8b 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -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*