MERGE: startswith and endswith don't accept None as slice index. Patc… · python/cpython@6159ee3 · GitHub
Skip to content

Commit 6159ee3

Browse files
committed
MERGE: startswith and endswith don't accept None as slice index. Patch by Torsten Becker. (closes #11828)
2 parents 25458f1 + ac45150 commit 6159ee3

8 files changed

Lines changed: 197 additions & 64 deletions

File tree

Lib/test/string_tests.py

Lines changed: 57 additions & 0 deletions

Lib/test/test_bytes.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,68 @@ def test_maketrans(self):
476476
self.assertRaises(ValueError, self.type2test.maketrans, b'abc', b'xyzq')
477477
self.assertRaises(TypeError, self.type2test.maketrans, 'abc', 'def')
478478

479+
def test_none_arguments(self):
480+
# issue 11828
481+
b = self.type2test(b'hello')
482+
l = self.type2test(b'l')
483+
h = self.type2test(b'h')
484+
x = self.type2test(b'x')
485+
o = self.type2test(b'o')
486+
487+
self.assertEqual(2, b.find(l, None))
488+
self.assertEqual(3, b.find(l, -2, None))
489+
self.assertEqual(2, b.find(l, None, -2))
490+
self.assertEqual(0, b.find(h, None, None))
491+
492+
self.assertEqual(3, b.rfind(l, None))
493+
self.assertEqual(3, b.rfind(l, -2, None))
494+
self.assertEqual(2, b.rfind(l, None, -2))
495+
self.assertEqual(0, b.rfind(h, None, None))
496+
497+
self.assertEqual(2, b.index(l, None))
498+
self.assertEqual(3, b.index(l, -2, None))
499+
self.assertEqual(2, b.index(l, None, -2))
500+
self.assertEqual(0, b.index(h, None, None))
501+
502+
self.assertEqual(3, b.rindex(l, None))
503+
self.assertEqual(3, b.rindex(l, -2, None))
504+
self.assertEqual(2, b.rindex(l, None, -2))
505+
self.assertEqual(0, b.rindex(h, None, None))
506+
507+
self.assertEqual(2, b.count(l, None))
508+
self.assertEqual(1, b.count(l, -2, None))
509+
self.assertEqual(1, b.count(l, None, -2))
510+
self.assertEqual(0, b.count(x, None, None))
511+
512+
self.assertEqual(True, b.endswith(o, None))
513+
self.assertEqual(True, b.endswith(o, -2, None))
514+
self.assertEqual(True, b.endswith(l, None, -2))
515+
self.assertEqual(False, b.endswith(x, None, None))
516+
517+
self.assertEqual(True, b.startswith(h, None))
518+
self.assertEqual(True, b.startswith(l, -2, None))
519+
self.assertEqual(True, b.startswith(h, None, -2))
520+
self.assertEqual(False, b.startswith(x, None, None))
521+
522+
def test_find_etc_raise_correct_error_messages(self):
523+
# issue 11828
524+
b = self.type2test(b'hello')
525+
x = self.type2test(b'x')
526+
self.assertRaisesRegexp(TypeError, r'\bfind\b', b.find,
527+
x, None, None, None)
528+
self.assertRaisesRegexp(TypeError, r'\brfind\b', b.rfind,
529+
x, None, None, None)
530+
self.assertRaisesRegexp(TypeError, r'\bindex\b', b.index,
531+
x, None, None, None)
532+
self.assertRaisesRegexp(TypeError, r'\brindex\b', b.rindex,
533+
x, None, None, None)
534+
self.assertRaisesRegexp(TypeError, r'\bcount\b', b.count,
535+
x, None, None, None)
536+
self.assertRaisesRegexp(TypeError, r'\bstartswith\b', b.startswith,
537+
x, None, None, None)
538+
self.assertRaisesRegexp(TypeError, r'\bendswith\b', b.endswith,
539+
x, None, None, None)
540+
479541

480542
class BytesTest(BaseBytesTest):
481543
type2test = bytes

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ Donald Beaudry
6666
David Beazley
6767
Robin Becker
6868
Neal Becker
69+
Torsten Becker
6970
Bill Bedford
7071
Stefan Behnel
7172
Reimer Behrends

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ Core and Builtins
4949
- Issue #11272: On Windows, input() strips '\r' (and not only '\n'), and
5050
sys.stdin uses universal newline (replace '\r\n' by '\n').
5151

52+
- issue #11828: startswith and endswith don't accept None as slice index.
53+
Patch by Torsten Becker.
54+
5255
- Issue #10830: Fix PyUnicode_FromFormatV("%c") for non-BMP characters on
5356
narrow build.
5457

Objects/bytearrayobject.c

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1081,8 +1081,8 @@ bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
10811081
Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
10821082
Py_ssize_t res;
10831083

1084-
if (!PyArg_ParseTuple(args, "O|O&O&:find/rfind/index/rindex", &subobj,
1085-
_PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1084+
if (!stringlib_parse_args_finds("find/rfind/index/rindex",
1085+
args, &subobj, &start, &end))
10861086
return -2;
10871087
if (_getbuffer(subobj, &subbuf) < 0)
10881088
return -2;
@@ -1132,8 +1132,7 @@ bytearray_count(PyByteArrayObject *self, PyObject *args)
11321132
Py_buffer vsub;
11331133
PyObject *count_obj;
11341134

1135-
if (!PyArg_ParseTuple(args, "O|O&O&:count", &sub_obj,
1136-
_PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1135+
if (!stringlib_parse_args_finds("count", args, &sub_obj, &start, &end))
11371136
return NULL;
11381137

11391138
if (_getbuffer(sub_obj, &vsub) < 0)
@@ -1291,8 +1290,7 @@ bytearray_startswith(PyByteArrayObject *self, PyObject *args)
12911290
PyObject *subobj;
12921291
int result;
12931292

1294-
if (!PyArg_ParseTuple(args, "O|O&O&:startswith", &subobj,
1295-
_PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1293+
if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end))
12961294
return NULL;
12971295
if (PyTuple_Check(subobj)) {
12981296
Py_ssize_t i;
@@ -1331,8 +1329,7 @@ bytearray_endswith(PyByteArrayObject *self, PyObject *args)
13311329
PyObject *subobj;
13321330
int result;
13331331

1334-
if (!PyArg_ParseTuple(args, "O|O&O&:endswith", &subobj,
1335-
_PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1332+
if (!stringlib_parse_args_finds("endswith", args, &subobj, &start, &end))
13361333
return NULL;
13371334
if (PyTuple_Check(subobj)) {
13381335
Py_ssize_t i;

Objects/bytesobject.c

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,19 +1244,9 @@ bytes_find_internal(PyBytesObject *self, PyObject *args, int dir)
12441244
const char *sub;
12451245
Py_ssize_t sub_len;
12461246
Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
1247-
PyObject *obj_start=Py_None, *obj_end=Py_None;
12481247

1249-
if (!PyArg_ParseTuple(args, "O|OO:find/rfind/index/rindex", &subobj,
1250-
&obj_start, &obj_end))
1251-
return -2;
1252-
/* To support None in "start" and "end" arguments, meaning
1253-
the same as if they were not passed.
1254-
*/
1255-
if (obj_start != Py_None)
1256-
if (!_PyEval_SliceIndex(obj_start, &start))
1257-
return -2;
1258-
if (obj_end != Py_None)
1259-
if (!_PyEval_SliceIndex(obj_end, &end))
1248+
if (!stringlib_parse_args_finds("find/rfind/index/rindex",
1249+
args, &subobj, &start, &end))
12601250
return -2;
12611251

12621252
if (PyBytes_Check(subobj)) {
@@ -1503,8 +1493,7 @@ bytes_count(PyBytesObject *self, PyObject *args)
15031493
Py_ssize_t sub_len;
15041494
Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
15051495

1506-
if (!PyArg_ParseTuple(args, "O|O&O&:count", &sub_obj,
1507-
_PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1496+
if (!stringlib_parse_args_finds("count", args, &sub_obj, &start, &end))
15081497
return NULL;
15091498

15101499
if (PyBytes_Check(sub_obj)) {
@@ -2222,8 +2211,7 @@ bytes_startswith(PyBytesObject *self, PyObject *args)
22222211
PyObject *subobj;
22232212
int result;
22242213

2225-
if (!PyArg_ParseTuple(args, "O|O&O&:startswith", &subobj,
2226-
_PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
2214+
if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end))
22272215
return NULL;
22282216
if (PyTuple_Check(subobj)) {
22292217
Py_ssize_t i;
@@ -2263,8 +2251,7 @@ bytes_endswith(PyBytesObject *self, PyObject *args)
22632251
PyObject *subobj;
22642252
int result;
22652253

2266-
if (!PyArg_ParseTuple(args, "O|O&O&:endswith", &subobj,
2267-
_PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
2254+
if (!stringlib_parse_args_finds("endswith", args, &subobj, &start, &end))
22682255
return NULL;
22692256
if (PyTuple_Check(subobj)) {
22702257
Py_ssize_t i;

Objects/stringlib/find.h

Lines changed: 48 additions & 19 deletions

0 commit comments

Comments
 (0)