mirror of https://github.com/python/cpython
bpo-20047: Make bytearray methods partition() and rpartition() rejecting (#4158)
separators that are not bytes-like objects.
This commit is contained in:
parent
5a4bbcd479
commit
a2314283ff
|
@ -2573,8 +2573,9 @@ arbitrary binary data.
|
||||||
bytearray.partition(sep)
|
bytearray.partition(sep)
|
||||||
|
|
||||||
Split the sequence at the first occurrence of *sep*, and return a 3-tuple
|
Split the sequence at the first occurrence of *sep*, and return a 3-tuple
|
||||||
containing the part before the separator, the separator, and the part
|
containing the part before the separator, the separator itself or its
|
||||||
after the separator. If the separator is not found, return a 3-tuple
|
bytearray copy, and the part after the separator.
|
||||||
|
If the separator is not found, return a 3-tuple
|
||||||
containing a copy of the original sequence, followed by two empty bytes or
|
containing a copy of the original sequence, followed by two empty bytes or
|
||||||
bytearray objects.
|
bytearray objects.
|
||||||
|
|
||||||
|
@ -2629,8 +2630,9 @@ arbitrary binary data.
|
||||||
bytearray.rpartition(sep)
|
bytearray.rpartition(sep)
|
||||||
|
|
||||||
Split the sequence at the last occurrence of *sep*, and return a 3-tuple
|
Split the sequence at the last occurrence of *sep*, and return a 3-tuple
|
||||||
containing the part before the separator, the separator, and the part
|
containing the part before the separator, the separator itself or its
|
||||||
after the separator. If the separator is not found, return a 3-tuple
|
bytearray copy, and the part after the separator.
|
||||||
|
If the separator is not found, return a 3-tuple
|
||||||
containing a copy of the original sequence, followed by two empty bytes or
|
containing a copy of the original sequence, followed by two empty bytes or
|
||||||
bytearray objects.
|
bytearray objects.
|
||||||
|
|
||||||
|
|
|
@ -548,8 +548,16 @@ class BaseBytesTest:
|
||||||
self.assertEqual(b.replace(b'i', b'a'), b'massassappa')
|
self.assertEqual(b.replace(b'i', b'a'), b'massassappa')
|
||||||
self.assertEqual(b.replace(b'ss', b'x'), b'mixixippi')
|
self.assertEqual(b.replace(b'ss', b'x'), b'mixixippi')
|
||||||
|
|
||||||
|
def test_replace_int_error(self):
|
||||||
|
self.assertRaises(TypeError, self.type2test(b'a b').replace, 32, b'')
|
||||||
|
|
||||||
def test_split_string_error(self):
|
def test_split_string_error(self):
|
||||||
self.assertRaises(TypeError, self.type2test(b'a b').split, ' ')
|
self.assertRaises(TypeError, self.type2test(b'a b').split, ' ')
|
||||||
|
self.assertRaises(TypeError, self.type2test(b'a b').rsplit, ' ')
|
||||||
|
|
||||||
|
def test_split_int_error(self):
|
||||||
|
self.assertRaises(TypeError, self.type2test(b'a b').split, 32)
|
||||||
|
self.assertRaises(TypeError, self.type2test(b'a b').rsplit, 32)
|
||||||
|
|
||||||
def test_split_unicodewhitespace(self):
|
def test_split_unicodewhitespace(self):
|
||||||
for b in (b'a\x1Cb', b'a\x1Db', b'a\x1Eb', b'a\x1Fb'):
|
for b in (b'a\x1Cb', b'a\x1Db', b'a\x1Eb', b'a\x1Fb'):
|
||||||
|
@ -558,9 +566,6 @@ class BaseBytesTest:
|
||||||
b = self.type2test(b"\x09\x0A\x0B\x0C\x0D\x1C\x1D\x1E\x1F")
|
b = self.type2test(b"\x09\x0A\x0B\x0C\x0D\x1C\x1D\x1E\x1F")
|
||||||
self.assertEqual(b.split(), [b'\x1c\x1d\x1e\x1f'])
|
self.assertEqual(b.split(), [b'\x1c\x1d\x1e\x1f'])
|
||||||
|
|
||||||
def test_rsplit_string_error(self):
|
|
||||||
self.assertRaises(TypeError, self.type2test(b'a b').rsplit, ' ')
|
|
||||||
|
|
||||||
def test_rsplit_unicodewhitespace(self):
|
def test_rsplit_unicodewhitespace(self):
|
||||||
b = self.type2test(b"\x09\x0A\x0B\x0C\x0D\x1C\x1D\x1E\x1F")
|
b = self.type2test(b"\x09\x0A\x0B\x0C\x0D\x1C\x1D\x1E\x1F")
|
||||||
self.assertEqual(b.rsplit(), [b'\x1c\x1d\x1e\x1f'])
|
self.assertEqual(b.rsplit(), [b'\x1c\x1d\x1e\x1f'])
|
||||||
|
@ -576,6 +581,14 @@ class BaseBytesTest:
|
||||||
self.assertEqual(b.rpartition(b'i'), (b'mississipp', b'i', b''))
|
self.assertEqual(b.rpartition(b'i'), (b'mississipp', b'i', b''))
|
||||||
self.assertEqual(b.rpartition(b'w'), (b'', b'', b'mississippi'))
|
self.assertEqual(b.rpartition(b'w'), (b'', b'', b'mississippi'))
|
||||||
|
|
||||||
|
def test_partition_string_error(self):
|
||||||
|
self.assertRaises(TypeError, self.type2test(b'a b').partition, ' ')
|
||||||
|
self.assertRaises(TypeError, self.type2test(b'a b').rpartition, ' ')
|
||||||
|
|
||||||
|
def test_partition_int_error(self):
|
||||||
|
self.assertRaises(TypeError, self.type2test(b'a b').partition, 32)
|
||||||
|
self.assertRaises(TypeError, self.type2test(b'a b').rpartition, 32)
|
||||||
|
|
||||||
def test_pickling(self):
|
def test_pickling(self):
|
||||||
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
|
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
|
||||||
for b in b"", b"a", b"abc", b"\xffab\x80", b"\0\0\377\0\0":
|
for b in b"", b"a", b"abc", b"\xffab\x80", b"\0\0\377\0\0":
|
||||||
|
@ -608,9 +621,14 @@ class BaseBytesTest:
|
||||||
self.assertEqual(self.type2test(b'abc').rstrip(memoryview(b'ac')), b'ab')
|
self.assertEqual(self.type2test(b'abc').rstrip(memoryview(b'ac')), b'ab')
|
||||||
|
|
||||||
def test_strip_string_error(self):
|
def test_strip_string_error(self):
|
||||||
self.assertRaises(TypeError, self.type2test(b'abc').strip, 'b')
|
self.assertRaises(TypeError, self.type2test(b'abc').strip, 'ac')
|
||||||
self.assertRaises(TypeError, self.type2test(b'abc').lstrip, 'b')
|
self.assertRaises(TypeError, self.type2test(b'abc').lstrip, 'ac')
|
||||||
self.assertRaises(TypeError, self.type2test(b'abc').rstrip, 'b')
|
self.assertRaises(TypeError, self.type2test(b'abc').rstrip, 'ac')
|
||||||
|
|
||||||
|
def test_strip_int_error(self):
|
||||||
|
self.assertRaises(TypeError, self.type2test(b' abc ').strip, 32)
|
||||||
|
self.assertRaises(TypeError, self.type2test(b' abc ').lstrip, 32)
|
||||||
|
self.assertRaises(TypeError, self.type2test(b' abc ').rstrip, 32)
|
||||||
|
|
||||||
def test_center(self):
|
def test_center(self):
|
||||||
# Fill character can be either bytes or bytearray (issue 12380)
|
# Fill character can be either bytes or bytearray (issue 12380)
|
||||||
|
@ -633,6 +651,11 @@ class BaseBytesTest:
|
||||||
self.assertEqual(b.rjust(7, fill_type(b'-')),
|
self.assertEqual(b.rjust(7, fill_type(b'-')),
|
||||||
self.type2test(b'----abc'))
|
self.type2test(b'----abc'))
|
||||||
|
|
||||||
|
def test_xjust_int_error(self):
|
||||||
|
self.assertRaises(TypeError, self.type2test(b'abc').center, 7, 32)
|
||||||
|
self.assertRaises(TypeError, self.type2test(b'abc').ljust, 7, 32)
|
||||||
|
self.assertRaises(TypeError, self.type2test(b'abc').rjust, 7, 32)
|
||||||
|
|
||||||
def test_ord(self):
|
def test_ord(self):
|
||||||
b = self.type2test(b'\0A\x7f\x80\xff')
|
b = self.type2test(b'\0A\x7f\x80\xff')
|
||||||
self.assertEqual([ord(b[i:i+1]) for i in range(len(b))],
|
self.assertEqual([ord(b[i:i+1]) for i in range(len(b))],
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
Bytearray methods partition() and rpartition() now accept only bytes-like
|
||||||
|
objects as separator, as documented. In particular they now raise TypeError
|
||||||
|
rather of returning a bogus result when an integer is passed as a separator.
|
|
@ -104,6 +104,26 @@ PyByteArray_FromObject(PyObject *input)
|
||||||
input, NULL);
|
input, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
_PyByteArray_FromBufferObject(PyObject *obj)
|
||||||
|
{
|
||||||
|
PyObject *result;
|
||||||
|
Py_buffer view;
|
||||||
|
|
||||||
|
if (PyObject_GetBuffer(obj, &view, PyBUF_FULL_RO) < 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
result = PyByteArray_FromStringAndSize(NULL, view.len);
|
||||||
|
if (result != NULL &&
|
||||||
|
PyBuffer_ToContiguous(PyByteArray_AS_STRING(result),
|
||||||
|
&view, view.len, 'C') < 0)
|
||||||
|
{
|
||||||
|
Py_CLEAR(result);
|
||||||
|
}
|
||||||
|
PyBuffer_Release(&view);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size)
|
PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size)
|
||||||
{
|
{
|
||||||
|
@ -536,7 +556,8 @@ bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
|
||||||
if (values == (PyObject *)self) {
|
if (values == (PyObject *)self) {
|
||||||
/* Make a copy and call this function recursively */
|
/* Make a copy and call this function recursively */
|
||||||
int err;
|
int err;
|
||||||
values = PyByteArray_FromObject(values);
|
values = PyByteArray_FromStringAndSize(PyByteArray_AS_STRING(values),
|
||||||
|
PyByteArray_GET_SIZE(values));
|
||||||
if (values == NULL)
|
if (values == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
err = bytearray_setslice(self, lo, hi, values);
|
err = bytearray_setslice(self, lo, hi, values);
|
||||||
|
@ -1387,19 +1408,19 @@ Partition the bytearray into three parts using the given separator.
|
||||||
|
|
||||||
This will search for the separator sep in the bytearray. If the separator is
|
This will search for the separator sep in the bytearray. If the separator is
|
||||||
found, returns a 3-tuple containing the part before the separator, the
|
found, returns a 3-tuple containing the part before the separator, the
|
||||||
separator itself, and the part after it.
|
separator itself, and the part after it as new bytearray objects.
|
||||||
|
|
||||||
If the separator is not found, returns a 3-tuple containing the original
|
If the separator is not found, returns a 3-tuple containing the copy of the
|
||||||
bytearray object and two empty bytearray objects.
|
original bytearray object and two empty bytearray objects.
|
||||||
[clinic start generated code]*/
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
bytearray_partition(PyByteArrayObject *self, PyObject *sep)
|
bytearray_partition(PyByteArrayObject *self, PyObject *sep)
|
||||||
/*[clinic end generated code: output=45d2525ddd35f957 input=86f89223892b70b5]*/
|
/*[clinic end generated code: output=45d2525ddd35f957 input=8f644749ee4fc83a]*/
|
||||||
{
|
{
|
||||||
PyObject *bytesep, *result;
|
PyObject *bytesep, *result;
|
||||||
|
|
||||||
bytesep = PyByteArray_FromObject(sep);
|
bytesep = _PyByteArray_FromBufferObject(sep);
|
||||||
if (! bytesep)
|
if (! bytesep)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -1420,23 +1441,24 @@ bytearray.rpartition
|
||||||
sep: object
|
sep: object
|
||||||
/
|
/
|
||||||
|
|
||||||
Partition the bytes into three parts using the given separator.
|
Partition the bytearray into three parts using the given separator.
|
||||||
|
|
||||||
This will search for the separator sep in the bytearray, starting and the end.
|
This will search for the separator sep in the bytearray, starting at the end.
|
||||||
If the separator is found, returns a 3-tuple containing the part before the
|
If the separator is found, returns a 3-tuple containing the part before the
|
||||||
separator, the separator itself, and the part after it.
|
separator, the separator itself, and the part after it as new bytearray
|
||||||
|
objects.
|
||||||
|
|
||||||
If the separator is not found, returns a 3-tuple containing two empty bytearray
|
If the separator is not found, returns a 3-tuple containing two empty bytearray
|
||||||
objects and the original bytearray object.
|
objects and the copy of the original bytearray object.
|
||||||
[clinic start generated code]*/
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
bytearray_rpartition(PyByteArrayObject *self, PyObject *sep)
|
bytearray_rpartition(PyByteArrayObject *self, PyObject *sep)
|
||||||
/*[clinic end generated code: output=440de3c9426115e8 input=5f4094f2de87c8f3]*/
|
/*[clinic end generated code: output=440de3c9426115e8 input=7e3df3e6cb8fa0ac]*/
|
||||||
{
|
{
|
||||||
PyObject *bytesep, *result;
|
PyObject *bytesep, *result;
|
||||||
|
|
||||||
bytesep = PyByteArray_FromObject(sep);
|
bytesep = _PyByteArray_FromBufferObject(sep);
|
||||||
if (! bytesep)
|
if (! bytesep)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
|
|
@ -1834,7 +1834,7 @@ bytes.rpartition
|
||||||
|
|
||||||
Partition the bytes into three parts using the given separator.
|
Partition the bytes into three parts using the given separator.
|
||||||
|
|
||||||
This will search for the separator sep in the bytes, starting and the end. If
|
This will search for the separator sep in the bytes, starting at the end. If
|
||||||
the separator is found, returns a 3-tuple containing the part before the
|
the separator is found, returns a 3-tuple containing the part before the
|
||||||
separator, the separator itself, and the part after it.
|
separator, the separator itself, and the part after it.
|
||||||
|
|
||||||
|
@ -1844,7 +1844,7 @@ objects and the original bytes object.
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
bytes_rpartition_impl(PyBytesObject *self, Py_buffer *sep)
|
bytes_rpartition_impl(PyBytesObject *self, Py_buffer *sep)
|
||||||
/*[clinic end generated code: output=191b114cbb028e50 input=67f689e63a62d478]*/
|
/*[clinic end generated code: output=191b114cbb028e50 input=d78db010c8cfdbe1]*/
|
||||||
{
|
{
|
||||||
return stringlib_rpartition(
|
return stringlib_rpartition(
|
||||||
(PyObject*) self,
|
(PyObject*) self,
|
||||||
|
|
|
@ -214,10 +214,10 @@ PyDoc_STRVAR(bytearray_partition__doc__,
|
||||||
"\n"
|
"\n"
|
||||||
"This will search for the separator sep in the bytearray. If the separator is\n"
|
"This will search for the separator sep in the bytearray. If the separator is\n"
|
||||||
"found, returns a 3-tuple containing the part before the separator, the\n"
|
"found, returns a 3-tuple containing the part before the separator, the\n"
|
||||||
"separator itself, and the part after it.\n"
|
"separator itself, and the part after it as new bytearray objects.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"If the separator is not found, returns a 3-tuple containing the original\n"
|
"If the separator is not found, returns a 3-tuple containing the copy of the\n"
|
||||||
"bytearray object and two empty bytearray objects.");
|
"original bytearray object and two empty bytearray objects.");
|
||||||
|
|
||||||
#define BYTEARRAY_PARTITION_METHODDEF \
|
#define BYTEARRAY_PARTITION_METHODDEF \
|
||||||
{"partition", (PyCFunction)bytearray_partition, METH_O, bytearray_partition__doc__},
|
{"partition", (PyCFunction)bytearray_partition, METH_O, bytearray_partition__doc__},
|
||||||
|
@ -226,14 +226,15 @@ PyDoc_STRVAR(bytearray_rpartition__doc__,
|
||||||
"rpartition($self, sep, /)\n"
|
"rpartition($self, sep, /)\n"
|
||||||
"--\n"
|
"--\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Partition the bytes into three parts using the given separator.\n"
|
"Partition the bytearray into three parts using the given separator.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"This will search for the separator sep in the bytearray, starting and the end.\n"
|
"This will search for the separator sep in the bytearray, starting at the end.\n"
|
||||||
"If the separator is found, returns a 3-tuple containing the part before the\n"
|
"If the separator is found, returns a 3-tuple containing the part before the\n"
|
||||||
"separator, the separator itself, and the part after it.\n"
|
"separator, the separator itself, and the part after it as new bytearray\n"
|
||||||
|
"objects.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"If the separator is not found, returns a 3-tuple containing two empty bytearray\n"
|
"If the separator is not found, returns a 3-tuple containing two empty bytearray\n"
|
||||||
"objects and the original bytearray object.");
|
"objects and the copy of the original bytearray object.");
|
||||||
|
|
||||||
#define BYTEARRAY_RPARTITION_METHODDEF \
|
#define BYTEARRAY_RPARTITION_METHODDEF \
|
||||||
{"rpartition", (PyCFunction)bytearray_rpartition, METH_O, bytearray_rpartition__doc__},
|
{"rpartition", (PyCFunction)bytearray_rpartition, METH_O, bytearray_rpartition__doc__},
|
||||||
|
@ -711,4 +712,4 @@ bytearray_sizeof(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
return bytearray_sizeof_impl(self);
|
return bytearray_sizeof_impl(self);
|
||||||
}
|
}
|
||||||
/*[clinic end generated code: output=e53f10084457a46b input=a9049054013a1b77]*/
|
/*[clinic end generated code: output=c2804d009182328c input=a9049054013a1b77]*/
|
||||||
|
|
|
@ -86,7 +86,7 @@ PyDoc_STRVAR(bytes_rpartition__doc__,
|
||||||
"\n"
|
"\n"
|
||||||
"Partition the bytes into three parts using the given separator.\n"
|
"Partition the bytes into three parts using the given separator.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"This will search for the separator sep in the bytes, starting and the end. If\n"
|
"This will search for the separator sep in the bytes, starting at the end. If\n"
|
||||||
"the separator is found, returns a 3-tuple containing the part before the\n"
|
"the separator is found, returns a 3-tuple containing the part before the\n"
|
||||||
"separator, the separator itself, and the part after it.\n"
|
"separator, the separator itself, and the part after it.\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
@ -499,4 +499,4 @@ bytes_fromhex(PyTypeObject *type, PyObject *arg)
|
||||||
exit:
|
exit:
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
/*[clinic end generated code: output=9e3374bd7d04c163 input=a9049054013a1b77]*/
|
/*[clinic end generated code: output=fc9e02359cc56d36 input=a9049054013a1b77]*/
|
||||||
|
|
|
@ -682,7 +682,7 @@ PyDoc_STRVAR(unicode_rpartition__doc__,
|
||||||
"\n"
|
"\n"
|
||||||
"Partition the string into three parts using the given separator.\n"
|
"Partition the string into three parts using the given separator.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"This will search for the separator in the string, starting and the end. If\n"
|
"This will search for the separator in the string, starting at the end. If\n"
|
||||||
"the separator is found, returns a 3-tuple containing the part before the\n"
|
"the separator is found, returns a 3-tuple containing the part before the\n"
|
||||||
"separator, the separator itself, and the part after it.\n"
|
"separator, the separator itself, and the part after it.\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
@ -930,4 +930,4 @@ unicode_sizeof(PyObject *self, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
return unicode_sizeof_impl(self);
|
return unicode_sizeof_impl(self);
|
||||||
}
|
}
|
||||||
/*[clinic end generated code: output=8fd799fd7f2cc724 input=a9049054013a1b77]*/
|
/*[clinic end generated code: output=816292e81a8a732e input=a9049054013a1b77]*/
|
||||||
|
|
|
@ -13067,7 +13067,7 @@ str.rpartition as unicode_rpartition = str.partition
|
||||||
|
|
||||||
Partition the string into three parts using the given separator.
|
Partition the string into three parts using the given separator.
|
||||||
|
|
||||||
This will search for the separator in the string, starting and the end. If
|
This will search for the separator in the string, starting at the end. If
|
||||||
the separator is found, returns a 3-tuple containing the part before the
|
the separator is found, returns a 3-tuple containing the part before the
|
||||||
separator, the separator itself, and the part after it.
|
separator, the separator itself, and the part after it.
|
||||||
|
|
||||||
|
@ -13077,7 +13077,7 @@ and the original string.
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
unicode_rpartition(PyObject *self, PyObject *sep)
|
unicode_rpartition(PyObject *self, PyObject *sep)
|
||||||
/*[clinic end generated code: output=1aa13cf1156572aa input=e77c7acb69bdfca6]*/
|
/*[clinic end generated code: output=1aa13cf1156572aa input=c4b7db3ef5cf336a]*/
|
||||||
{
|
{
|
||||||
return PyUnicode_RPartition(self, sep);
|
return PyUnicode_RPartition(self, sep);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue