Issue #12380: PyArg_ParseTuple now accepts a bytearray for the 'c' format.

As a side effect, this now allows the rjust, ljust and center methods of
bytes and bytearray to accept a bytearray argument.

Patch by Petri Lehtinen
This commit is contained in:
Eli Bendersky 2011-07-29 07:05:08 +03:00
parent 66d2be8986
commit 906b88fb2a
6 changed files with 53 additions and 4 deletions

View File

@ -260,9 +260,11 @@ Numbers
``n`` (:class:`int`) [Py_ssize_t]
Convert a Python integer to a C :c:type:`Py_ssize_t`.
``c`` (:class:`bytes` of length 1) [char]
Convert a Python byte, represented as a :class:`bytes` object of length 1,
to a C :c:type:`char`.
``c`` (:class:`bytes` or :class:`bytearray` of length 1) [char]
Convert a Python byte, represented as a :class:`bytes` or
:class:`bytearray` object of length 1, to a C :c:type:`char`.
.. versionchanged:: 3.3 Allow :class:`bytearray` objects
``C`` (:class:`str` of length 1) [int]
Convert a Python character, represented as a :class:`str` object of

View File

@ -475,6 +475,27 @@ class BaseBytesTest(unittest.TestCase):
self.assertRaises(TypeError, self.type2test(b'abc').lstrip, 'b')
self.assertRaises(TypeError, self.type2test(b'abc').rstrip, 'b')
def test_center(self):
# Fill character can be either bytes or bytearray (issue 12380)
b = self.type2test(b'abc')
for fill_type in (bytes, bytearray):
self.assertEqual(b.center(7, fill_type(b'-')),
self.type2test(b'--abc--'))
def test_ljust(self):
# Fill character can be either bytes or bytearray (issue 12380)
b = self.type2test(b'abc')
for fill_type in (bytes, bytearray):
self.assertEqual(b.ljust(7, fill_type(b'-')),
self.type2test(b'abc----'))
def test_rjust(self):
# Fill character can be either bytes or bytearray (issue 12380)
b = self.type2test(b'abc')
for fill_type in (bytes, bytearray):
self.assertEqual(b.rjust(7, fill_type(b'-')),
self.type2test(b'----abc'))
def test_ord(self):
b = self.type2test(b'\0A\x7f\x80\xff')
self.assertEqual([ord(b[i:i+1]) for i in range(len(b))],

View File

@ -294,6 +294,15 @@ class Keywords_TestCase(unittest.TestCase):
self.fail('TypeError should have been raised')
class Bytes_TestCase(unittest.TestCase):
def test_c(self):
from _testcapi import getargs_c
self.assertRaises(TypeError, getargs_c, b'abc') # len > 1
self.assertEqual(getargs_c(b'a'), b'a')
self.assertEqual(getargs_c(bytearray(b'a')), b'a')
self.assertRaises(TypeError, getargs_c, memoryview(b'a'))
self.assertRaises(TypeError, getargs_c, 's')
self.assertRaises(TypeError, getargs_c, None)
def test_s(self):
from _testcapi import getargs_s
self.assertEqual(getargs_s('abc\xe9'), b'abc\xc3\xa9')

View File

@ -238,6 +238,9 @@ Core and Builtins
- Issue #11386: bytearray.pop() now throws IndexError when the bytearray is
empty, instead of OverflowError.
- Issue #12380: The rjust, ljust and center methods of bytes and bytearray
now accept a bytearray argument.
Library
-------
@ -1282,6 +1285,8 @@ C-API
- Issue #12173: The first argument of PyImport_ImportModuleLevel is now `const
char *` instead of `char *`.
- Issue #12380: PyArg_ParseTuple now accepts a bytearray for the 'c' format.
Documentation
-------------
@ -6680,4 +6685,4 @@ Docs
----
**(For information about older versions, consult the HISTORY file.)**
**(For information about older versions, consult the HISTORY file.)**

View File

@ -1002,6 +1002,15 @@ test_k_code(PyObject *self)
return Py_None;
}
static PyObject *
getargs_c(PyObject *self, PyObject *args)
{
char c;
if (!PyArg_ParseTuple(args, "c", &c))
return NULL;
return PyBytes_FromStringAndSize(&c, 1);
}
static PyObject *
getargs_s(PyObject *self, PyObject *args)
{
@ -2289,6 +2298,7 @@ static PyMethodDef TestMethods[] = {
(PyCFunction)test_long_long_and_overflow, METH_NOARGS},
{"test_L_code", (PyCFunction)test_L_code, METH_NOARGS},
#endif
{"getargs_c", getargs_c, METH_VARARGS},
{"getargs_s", getargs_s, METH_VARARGS},
{"getargs_s_star", getargs_s_star, METH_VARARGS},
{"getargs_s_hash", getargs_s_hash, METH_VARARGS},

View File

@ -828,6 +828,8 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
char *p = va_arg(*p_va, char *);
if (PyBytes_Check(arg) && PyBytes_Size(arg) == 1)
*p = PyBytes_AS_STRING(arg)[0];
else if (PyByteArray_Check(arg) && PyByteArray_Size(arg) == 1)
*p = PyByteArray_AS_STRING(arg)[0];
else
return converterr("a byte string of length 1", arg, msgbuf, bufsize);
break;