diff --git a/Lib/bisect.py b/Lib/bisect.py index ca6ca7240840bb..cd5c1d6eccd8ed 100644 --- a/Lib/bisect.py +++ b/Lib/bisect.py @@ -33,7 +33,7 @@ def bisect_right(a, x, lo=0, hi=None, *, key=None): if lo < 0: raise ValueError('lo must be non-negative') - if hi is None: + if hi is None or hi < 0: hi = len(a) # Note, the comparison uses "<" to match the # __lt__() logic in list.sort() and in heapq. @@ -86,7 +86,7 @@ def bisect_left(a, x, lo=0, hi=None, *, key=None): if lo < 0: raise ValueError('lo must be non-negative') - if hi is None: + if hi is None or hi < 0: hi = len(a) # Note, the comparison uses "<" to match the # __lt__() logic in list.sort() and in heapq. diff --git a/Lib/test/test_bisect.py b/Lib/test/test_bisect.py index 97204d4cad3871..bf672171df2208 100644 --- a/Lib/test/test_bisect.py +++ b/Lib/test/test_bisect.py @@ -118,13 +118,18 @@ def test_precomputed(self): self.assertEqual(func(data, elem), expected) self.assertEqual(func(UserList(data), elem), expected) - def test_negative_lo(self): + def test_negative_hi_lo(self): # Issue 3301 mod = self.module self.assertRaises(ValueError, mod.bisect_left, [1, 2, 3], 5, -1, 3) self.assertRaises(ValueError, mod.bisect_right, [1, 2, 3], 5, -1, 3) self.assertRaises(ValueError, mod.insort_left, [1, 2, 3], 5, -1, 3) self.assertRaises(ValueError, mod.insort_right, [1, 2, 3], 5, -1, 3) + # Test c implementation + self.assertRaises(ValueError, c_bisect.bisect_left, [1, 2, 3], 5, 3, -2) + self.assertRaises(ValueError, c_bisect.bisect_right, [1, 2, 3], 5, 3, -2) + self.assertRaises(ValueError, c_bisect.insort_left, [1, 2, 3], 5, 3, -2) + self.assertRaises(ValueError, c_bisect.insort_right, [1, 2, 3], 5, 3, -2) def test_large_range(self): # Issue 13496 diff --git a/Misc/NEWS.d/next/Library/2024-10-24-15-21-03.gh-issue-125889.P9MXpN.rst b/Misc/NEWS.d/next/Library/2024-10-24-15-21-03.gh-issue-125889.P9MXpN.rst new file mode 100644 index 00000000000000..05b9df3356d6b7 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-24-15-21-03.gh-issue-125889.P9MXpN.rst @@ -0,0 +1 @@ +Allow negative values ​​for ``hi`` argument of ``bisect_left/right`` and ``insort_left/right``. diff --git a/Modules/_bisectmodule.c b/Modules/_bisectmodule.c index 56322c48b7cd35..43e86c8785fa30 100644 --- a/Modules/_bisectmodule.c +++ b/Modules/_bisectmodule.c @@ -66,6 +66,10 @@ internal_bisect_right(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t if (hi < 0) return -1; } + if (hi < 0) { + PyErr_SetString(PyExc_ValueError, "hi must be non-negative"); + return -1; + } ssizeargfunc sq_item = get_sq_item(list); if (sq_item == NULL) { return -1; @@ -250,6 +254,10 @@ internal_bisect_left(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t h if (hi < 0) return -1; } + if (hi < 0) { + PyErr_SetString(PyExc_ValueError, "hi must be non-negative"); + return -1; + } ssizeargfunc sq_item = get_sq_item(list); if (sq_item == NULL) { return -1;