#17806: Added keyword-argument support for "tabsize" to str/bytes.expandtabs().

This commit is contained in:
Ezio Melotti 2013-11-16 19:10:57 +02:00
parent b41c2547e0
commit 745d54d2fa
8 changed files with 51 additions and 23 deletions

View file

@ -1523,7 +1523,7 @@ expression support in the :mod:`re` module).
at that position. at that position.
.. method:: str.expandtabs([tabsize]) .. method:: str.expandtabs(tabsize=8)
Return a copy of the string where all tab characters are replaced by one or Return a copy of the string where all tab characters are replaced by one or
more spaces, depending on the current column and the given tab size. Tab more spaces, depending on the current column and the given tab size. Tab

View file

@ -160,14 +160,20 @@ class MixinBytesBufferCommonTests(object):
self.marshal(b'abc\rab\tdef\ng\thi').expandtabs(8)) self.marshal(b'abc\rab\tdef\ng\thi').expandtabs(8))
self.assertEqual(b'abc\rab def\ng hi', self.assertEqual(b'abc\rab def\ng hi',
self.marshal(b'abc\rab\tdef\ng\thi').expandtabs(4)) self.marshal(b'abc\rab\tdef\ng\thi').expandtabs(4))
self.assertEqual(b'abc\r\nab def\ng hi',
self.marshal(b'abc\r\nab\tdef\ng\thi').expandtabs())
self.assertEqual(b'abc\r\nab def\ng hi',
self.marshal(b'abc\r\nab\tdef\ng\thi').expandtabs(8))
self.assertEqual(b'abc\r\nab def\ng hi', self.assertEqual(b'abc\r\nab def\ng hi',
self.marshal(b'abc\r\nab\tdef\ng\thi').expandtabs(4)) self.marshal(b'abc\r\nab\tdef\ng\thi').expandtabs(4))
self.assertEqual(b'abc\rab def\ng hi',
self.marshal(b'abc\rab\tdef\ng\thi').expandtabs())
self.assertEqual(b'abc\rab def\ng hi',
self.marshal(b'abc\rab\tdef\ng\thi').expandtabs(8))
self.assertEqual(b'abc\r\nab\r\ndef\ng\r\nhi', self.assertEqual(b'abc\r\nab\r\ndef\ng\r\nhi',
self.marshal(b'abc\r\nab\r\ndef\ng\r\nhi').expandtabs(4)) self.marshal(b'abc\r\nab\r\ndef\ng\r\nhi').expandtabs(4))
# check keyword args
self.assertEqual(b'abc\rab def\ng hi',
self.marshal(b'abc\rab\tdef\ng\thi').expandtabs(tabsize=8))
self.assertEqual(b'abc\rab def\ng hi',
self.marshal(b'abc\rab\tdef\ng\thi').expandtabs(tabsize=4))
self.assertEqual(b' a\n b', self.marshal(b' \ta\n\tb').expandtabs(1)) self.assertEqual(b' a\n b', self.marshal(b' \ta\n\tb').expandtabs(1))
self.assertRaises(TypeError, self.marshal(b'hello').expandtabs, 42, 42) self.assertRaises(TypeError, self.marshal(b'hello').expandtabs, 42, 42)

View file

@ -328,13 +328,26 @@ class BaseTest:
self.checkraises(TypeError, 'hello', 'upper', 42) self.checkraises(TypeError, 'hello', 'upper', 42)
def test_expandtabs(self): def test_expandtabs(self):
self.checkequal('abc\rab def\ng hi', 'abc\rab\tdef\ng\thi', 'expandtabs') self.checkequal('abc\rab def\ng hi', 'abc\rab\tdef\ng\thi',
self.checkequal('abc\rab def\ng hi', 'abc\rab\tdef\ng\thi', 'expandtabs', 8) 'expandtabs')
self.checkequal('abc\rab def\ng hi', 'abc\rab\tdef\ng\thi', 'expandtabs', 4) self.checkequal('abc\rab def\ng hi', 'abc\rab\tdef\ng\thi',
self.checkequal('abc\r\nab def\ng hi', 'abc\r\nab\tdef\ng\thi', 'expandtabs', 4) 'expandtabs', 8)
self.checkequal('abc\rab def\ng hi', 'abc\rab\tdef\ng\thi', 'expandtabs') self.checkequal('abc\rab def\ng hi', 'abc\rab\tdef\ng\thi',
self.checkequal('abc\rab def\ng hi', 'abc\rab\tdef\ng\thi', 'expandtabs', 8) 'expandtabs', 4)
self.checkequal('abc\r\nab\r\ndef\ng\r\nhi', 'abc\r\nab\r\ndef\ng\r\nhi', 'expandtabs', 4) self.checkequal('abc\r\nab def\ng hi', 'abc\r\nab\tdef\ng\thi',
'expandtabs')
self.checkequal('abc\r\nab def\ng hi', 'abc\r\nab\tdef\ng\thi',
'expandtabs', 8)
self.checkequal('abc\r\nab def\ng hi', 'abc\r\nab\tdef\ng\thi',
'expandtabs', 4)
self.checkequal('abc\r\nab\r\ndef\ng\r\nhi', 'abc\r\nab\r\ndef\ng\r\nhi',
'expandtabs', 4)
# check keyword args
self.checkequal('abc\rab def\ng hi', 'abc\rab\tdef\ng\thi',
'expandtabs', tabsize=8)
self.checkequal('abc\rab def\ng hi', 'abc\rab\tdef\ng\thi',
'expandtabs', tabsize=4)
self.checkequal(' a\n b', ' \ta\n\tb', 'expandtabs', 1) self.checkequal(' a\n b', ' \ta\n\tb', 'expandtabs', 1)
self.checkraises(TypeError, 'hello', 'expandtabs', 42, 42) self.checkraises(TypeError, 'hello', 'expandtabs', 42, 42)

View file

@ -10,6 +10,9 @@ Projected release date: 2013-11-24
Core and Builtins Core and Builtins
----------------- -----------------
- Issue #17806: Added keyword-argument support for "tabsize" to
str/bytes.expandtabs().
- Issue #17828: Output type errors in str.encode(), bytes.decode() and - Issue #17828: Output type errors in str.encode(), bytes.decode() and
bytearray.decode() now direct users to codecs.encode() or codecs.decode() bytearray.decode() now direct users to codecs.encode() or codecs.decode()
as appropriate. as appropriate.

View file

@ -2805,7 +2805,7 @@ bytearray_methods[] = {
{"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__}, {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__},
{"decode", (PyCFunction)bytearray_decode, METH_VARARGS | METH_KEYWORDS, decode_doc}, {"decode", (PyCFunction)bytearray_decode, METH_VARARGS | METH_KEYWORDS, decode_doc},
{"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__}, {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__},
{"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS, {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS | METH_KEYWORDS,
expandtabs__doc__}, expandtabs__doc__},
{"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__}, {"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__},
{"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__}, {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__},

View file

@ -2389,7 +2389,7 @@ bytes_methods[] = {
{"decode", (PyCFunction)bytes_decode, METH_VARARGS | METH_KEYWORDS, decode__doc__}, {"decode", (PyCFunction)bytes_decode, METH_VARARGS | METH_KEYWORDS, decode__doc__},
{"endswith", (PyCFunction)bytes_endswith, METH_VARARGS, {"endswith", (PyCFunction)bytes_endswith, METH_VARARGS,
endswith__doc__}, endswith__doc__},
{"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS, {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS | METH_KEYWORDS,
expandtabs__doc__}, expandtabs__doc__},
{"find", (PyCFunction)bytes_find, METH_VARARGS, find__doc__}, {"find", (PyCFunction)bytes_find, METH_VARARGS, find__doc__},
{"fromhex", (PyCFunction)bytes_fromhex, METH_VARARGS|METH_CLASS, {"fromhex", (PyCFunction)bytes_fromhex, METH_VARARGS|METH_CLASS,

View file

@ -5,21 +5,23 @@
shared code in bytes_methods.c to cut down on duplicate code bloat. */ shared code in bytes_methods.c to cut down on duplicate code bloat. */
PyDoc_STRVAR(expandtabs__doc__, PyDoc_STRVAR(expandtabs__doc__,
"B.expandtabs([tabsize]) -> copy of B\n\ "B.expandtabs(tabsize=8) -> copy of B\n\
\n\ \n\
Return a copy of B where all tab characters are expanded using spaces.\n\ Return a copy of B where all tab characters are expanded using spaces.\n\
If tabsize is not given, a tab size of 8 characters is assumed."); If tabsize is not given, a tab size of 8 characters is assumed.");
static PyObject* static PyObject*
stringlib_expandtabs(PyObject *self, PyObject *args) stringlib_expandtabs(PyObject *self, PyObject *args, PyObject *kwds)
{ {
const char *e, *p; const char *e, *p;
char *q; char *q;
size_t i, j; size_t i, j;
PyObject *u; PyObject *u;
static char *kwlist[] = {"tabsize", 0};
int tabsize = 8; int tabsize = 8;
if (!PyArg_ParseTuple(args, "|i:expandtabs", &tabsize)) if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:expandtabs",
kwlist, &tabsize))
return NULL; return NULL;
/* First pass: determine size of output string */ /* First pass: determine size of output string */

View file

@ -11010,23 +11010,25 @@ unicode_encode(PyObject *self, PyObject *args, PyObject *kwargs)
} }
PyDoc_STRVAR(expandtabs__doc__, PyDoc_STRVAR(expandtabs__doc__,
"S.expandtabs([tabsize]) -> str\n\ "S.expandtabs(tabsize=8) -> str\n\
\n\ \n\
Return a copy of S where all tab characters are expanded using spaces.\n\ Return a copy of S where all tab characters are expanded using spaces.\n\
If tabsize is not given, a tab size of 8 characters is assumed."); If tabsize is not given, a tab size of 8 characters is assumed.");
static PyObject* static PyObject*
unicode_expandtabs(PyObject *self, PyObject *args) unicode_expandtabs(PyObject *self, PyObject *args, PyObject *kwds)
{ {
Py_ssize_t i, j, line_pos, src_len, incr; Py_ssize_t i, j, line_pos, src_len, incr;
Py_UCS4 ch; Py_UCS4 ch;
PyObject *u; PyObject *u;
void *src_data, *dest_data; void *src_data, *dest_data;
static char *kwlist[] = {"tabsize", 0};
int tabsize = 8; int tabsize = 8;
int kind; int kind;
int found; int found;
if (!PyArg_ParseTuple(args, "|i:expandtabs", &tabsize)) if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:expandtabs",
kwlist, &tabsize))
return NULL; return NULL;
if (PyUnicode_READY(self) == -1) if (PyUnicode_READY(self) == -1)
@ -13394,7 +13396,8 @@ static PyMethodDef unicode_methods[] = {
{"title", (PyCFunction) unicode_title, METH_NOARGS, title__doc__}, {"title", (PyCFunction) unicode_title, METH_NOARGS, title__doc__},
{"center", (PyCFunction) unicode_center, METH_VARARGS, center__doc__}, {"center", (PyCFunction) unicode_center, METH_VARARGS, center__doc__},
{"count", (PyCFunction) unicode_count, METH_VARARGS, count__doc__}, {"count", (PyCFunction) unicode_count, METH_VARARGS, count__doc__},
{"expandtabs", (PyCFunction) unicode_expandtabs, METH_VARARGS, expandtabs__doc__}, {"expandtabs", (PyCFunction) unicode_expandtabs,
METH_VARARGS | METH_KEYWORDS, expandtabs__doc__},
{"find", (PyCFunction) unicode_find, METH_VARARGS, find__doc__}, {"find", (PyCFunction) unicode_find, METH_VARARGS, find__doc__},
{"partition", (PyCFunction) unicode_partition, METH_O, partition__doc__}, {"partition", (PyCFunction) unicode_partition, METH_O, partition__doc__},
{"index", (PyCFunction) unicode_index, METH_VARARGS, index__doc__}, {"index", (PyCFunction) unicode_index, METH_VARARGS, index__doc__},
@ -13406,7 +13409,8 @@ static PyMethodDef unicode_methods[] = {
{"rjust", (PyCFunction) unicode_rjust, METH_VARARGS, rjust__doc__}, {"rjust", (PyCFunction) unicode_rjust, METH_VARARGS, rjust__doc__},
{"rstrip", (PyCFunction) unicode_rstrip, METH_VARARGS, rstrip__doc__}, {"rstrip", (PyCFunction) unicode_rstrip, METH_VARARGS, rstrip__doc__},
{"rpartition", (PyCFunction) unicode_rpartition, METH_O, rpartition__doc__}, {"rpartition", (PyCFunction) unicode_rpartition, METH_O, rpartition__doc__},
{"splitlines", (PyCFunction) unicode_splitlines, METH_VARARGS | METH_KEYWORDS, splitlines__doc__}, {"splitlines", (PyCFunction) unicode_splitlines,
METH_VARARGS | METH_KEYWORDS, splitlines__doc__},
{"strip", (PyCFunction) unicode_strip, METH_VARARGS, strip__doc__}, {"strip", (PyCFunction) unicode_strip, METH_VARARGS, strip__doc__},
{"swapcase", (PyCFunction) unicode_swapcase, METH_NOARGS, swapcase__doc__}, {"swapcase", (PyCFunction) unicode_swapcase, METH_NOARGS, swapcase__doc__},
{"translate", (PyCFunction) unicode_translate, METH_O, translate__doc__}, {"translate", (PyCFunction) unicode_translate, METH_O, translate__doc__},