summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEzio Melotti <ezio.melotti@gmail.com>2013-11-16 17:10:57 (GMT)
committerEzio Melotti <ezio.melotti@gmail.com>2013-11-16 17:10:57 (GMT)
commit745d54d2fa1870bbb933579b390fdd1702874ead (patch)
tree9e0560c56181a5dea12bf970862db77dddba6afd
parentb41c2547e0a5fa75d436d824e5f09f2327354e1a (diff)
downloadcpython-745d54d2fa1870bbb933579b390fdd1702874ead.zip
cpython-745d54d2fa1870bbb933579b390fdd1702874ead.tar.gz
cpython-745d54d2fa1870bbb933579b390fdd1702874ead.tar.bz2
#17806: Added keyword-argument support for "tabsize" to str/bytes.expandtabs().
-rw-r--r--Doc/library/stdtypes.rst2
-rw-r--r--Lib/test/buffer_tests.py16
-rw-r--r--Lib/test/string_tests.py27
-rw-r--r--Misc/NEWS3
-rw-r--r--Objects/bytearrayobject.c2
-rw-r--r--Objects/bytesobject.c2
-rw-r--r--Objects/stringlib/transmogrify.h8
-rw-r--r--Objects/unicodeobject.c14
8 files changed, 51 insertions, 23 deletions
diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst
index 04d01f4..8c11c1b 100644
--- a/Doc/library/stdtypes.rst
+++ b/Doc/library/stdtypes.rst
@@ -1523,7 +1523,7 @@ expression support in the :mod:`re` module).
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
more spaces, depending on the current column and the given tab size. Tab
diff --git a/Lib/test/buffer_tests.py b/Lib/test/buffer_tests.py
index cf54c28..0a62940 100644
--- a/Lib/test/buffer_tests.py
+++ b/Lib/test/buffer_tests.py
@@ -160,14 +160,20 @@ class MixinBytesBufferCommonTests(object):
self.marshal(b'abc\rab\tdef\ng\thi').expandtabs(8))
self.assertEqual(b'abc\rab def\ng hi',
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.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.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.assertRaises(TypeError, self.marshal(b'hello').expandtabs, 42, 42)
diff --git a/Lib/test/string_tests.py b/Lib/test/string_tests.py
index 1d70385..30784d4 100644
--- a/Lib/test/string_tests.py
+++ b/Lib/test/string_tests.py
@@ -328,13 +328,26 @@ class BaseTest:
self.checkraises(TypeError, 'hello', 'upper', 42)
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', 'expandtabs', 8)
- self.checkequal('abc\rab def\ng hi', 'abc\rab\tdef\ng\thi', 'expandtabs', 4)
- self.checkequal('abc\r\nab def\ng hi', 'abc\r\nab\tdef\ng\thi', 'expandtabs', 4)
- 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', 'expandtabs', 8)
- self.checkequal('abc\r\nab\r\ndef\ng\r\nhi', 'abc\r\nab\r\ndef\ng\r\nhi', 'expandtabs', 4)
+ 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',
+ 'expandtabs', 8)
+ self.checkequal('abc\rab def\ng hi', 'abc\rab\tdef\ng\thi',
+ '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.checkraises(TypeError, 'hello', 'expandtabs', 42, 42)
diff --git a/Misc/NEWS b/Misc/NEWS
index 2c0508c..89c37d9 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,9 @@ Projected release date: 2013-11-24
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
bytearray.decode() now direct users to codecs.encode() or codecs.decode()
as appropriate.
diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c
index 2358e05..400da1c 100644
--- a/Objects/bytearrayobject.c
+++ b/Objects/bytearrayobject.c
@@ -2805,7 +2805,7 @@ bytearray_methods[] = {
{"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__},
{"decode", (PyCFunction)bytearray_decode, METH_VARARGS | METH_KEYWORDS, decode_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__},
{"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__},
{"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__},
diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c
index 0a9d04d..efa0192 100644
--- a/Objects/bytesobject.c
+++ b/Objects/bytesobject.c
@@ -2389,7 +2389,7 @@ bytes_methods[] = {
{"decode", (PyCFunction)bytes_decode, METH_VARARGS | METH_KEYWORDS, decode__doc__},
{"endswith", (PyCFunction)bytes_endswith, METH_VARARGS,
endswith__doc__},
- {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS,
+ {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS | METH_KEYWORDS,
expandtabs__doc__},
{"find", (PyCFunction)bytes_find, METH_VARARGS, find__doc__},
{"fromhex", (PyCFunction)bytes_fromhex, METH_VARARGS|METH_CLASS,
diff --git a/Objects/stringlib/transmogrify.h b/Objects/stringlib/transmogrify.h
index 90fa129..dd00976 100644
--- a/Objects/stringlib/transmogrify.h
+++ b/Objects/stringlib/transmogrify.h
@@ -5,21 +5,23 @@
shared code in bytes_methods.c to cut down on duplicate code bloat. */
PyDoc_STRVAR(expandtabs__doc__,
-"B.expandtabs([tabsize]) -> copy of B\n\
+"B.expandtabs(tabsize=8) -> copy of B\n\
\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.");
static PyObject*
-stringlib_expandtabs(PyObject *self, PyObject *args)
+stringlib_expandtabs(PyObject *self, PyObject *args, PyObject *kwds)
{
const char *e, *p;
char *q;
size_t i, j;
PyObject *u;
+ static char *kwlist[] = {"tabsize", 0};
int tabsize = 8;
- if (!PyArg_ParseTuple(args, "|i:expandtabs", &tabsize))
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:expandtabs",
+ kwlist, &tabsize))
return NULL;
/* First pass: determine size of output string */
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 7789816..925d86c 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -11010,23 +11010,25 @@ unicode_encode(PyObject *self, PyObject *args, PyObject *kwargs)
}
PyDoc_STRVAR(expandtabs__doc__,
- "S.expandtabs([tabsize]) -> str\n\
+ "S.expandtabs(tabsize=8) -> str\n\
\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.");
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_UCS4 ch;
PyObject *u;
void *src_data, *dest_data;
+ static char *kwlist[] = {"tabsize", 0};
int tabsize = 8;
int kind;
int found;
- if (!PyArg_ParseTuple(args, "|i:expandtabs", &tabsize))
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:expandtabs",
+ kwlist, &tabsize))
return NULL;
if (PyUnicode_READY(self) == -1)
@@ -13394,7 +13396,8 @@ static PyMethodDef unicode_methods[] = {
{"title", (PyCFunction) unicode_title, METH_NOARGS, title__doc__},
{"center", (PyCFunction) unicode_center, METH_VARARGS, center__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__},
{"partition", (PyCFunction) unicode_partition, METH_O, partition__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__},
{"rstrip", (PyCFunction) unicode_rstrip, METH_VARARGS, rstrip__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__},
{"swapcase", (PyCFunction) unicode_swapcase, METH_NOARGS, swapcase__doc__},
{"translate", (PyCFunction) unicode_translate, METH_O, translate__doc__},