Skip to content

Commit afd1265

Browse files
ZackerySpytzPhaqui
andauthored
bpo-31956: Add start and stop parameters to array.index() (GH-25059)
Co-Authored-By: Anders Lorentsen <Phaqui@gmail.com>
1 parent 240bcf8 commit afd1265

File tree

6 files changed

+87
-12
lines changed

6 files changed

+87
-12
lines changed

Doc/library/array.rst

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,11 +178,15 @@ The following data items and methods are also supported:
178178
array of some other type.
179179

180180

181-
.. method:: array.index(x)
181+
.. method:: array.index(x[, start[, stop]])
182182

183183
Return the smallest *i* such that *i* is the index of the first occurrence of
184-
*x* in the array.
184+
*x* in the array. The optional arguments *start* and *stop* can be
185+
specified to search for *x* within a subsection of the array. Raise
186+
:exc:`ValueError` if *x* is not found.
185187

188+
.. versionchanged:: 3.10
189+
Added optional *start* and *stop* parameters.
186190

187191
.. method:: array.insert(i, x)
188192

Doc/whatsnew/3.10.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,13 @@ argparse
633633
Misleading phrase "optional arguments" was replaced with "options" in argparse help. Some tests might require adaptation if they rely on exact output match.
634634
(Contributed by Raymond Hettinger in :issue:`9694`.)
635635
636+
array
637+
-----
638+
639+
The :meth:`~array.array.index` method of :class:`array.array` now has
640+
optional *start* and *stop* parameters.
641+
(Contributed by Anders Lorentsen and Zackery Spytz in :issue:`31956`.)
642+
636643
base64
637644
------
638645

Lib/test/test_array.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -918,6 +918,17 @@ def test_index(self):
918918
self.assertRaises(ValueError, a.index, None)
919919
self.assertRaises(ValueError, a.index, self.outside)
920920

921+
a = array.array('i', [-2, -1, 0, 0, 1, 2])
922+
self.assertEqual(a.index(0), 2)
923+
self.assertEqual(a.index(0, 2), 2)
924+
self.assertEqual(a.index(0, -4), 2)
925+
self.assertEqual(a.index(-2, -10), 0)
926+
self.assertEqual(a.index(0, 3), 3)
927+
self.assertEqual(a.index(0, -3), 3)
928+
self.assertEqual(a.index(0, 3, 4), 3)
929+
self.assertEqual(a.index(0, -3, -2), 3)
930+
self.assertRaises(ValueError, a.index, 2, 0, -10)
931+
921932
def test_count(self):
922933
example = 2*self.example
923934
a = array.array(self.typecode, example)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
The :meth:`~array.array.index` method of :class:`array.array` now has
2+
optional *start* and *stop* parameters.

Modules/arraymodule.c

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1136,18 +1136,32 @@ array_array_count(arrayobject *self, PyObject *v)
11361136
array.array.index
11371137
11381138
v: object
1139+
start: slice_index(accept={int}) = 0
1140+
stop: slice_index(accept={int}, c_default="PY_SSIZE_T_MAX") = sys.maxsize
11391141
/
11401142
11411143
Return index of first occurrence of v in the array.
1144+
1145+
Raise ValueError if the value is not present.
11421146
[clinic start generated code]*/
11431147

11441148
static PyObject *
1145-
array_array_index(arrayobject *self, PyObject *v)
1146-
/*[clinic end generated code: output=d48498d325602167 input=cf619898c6649d08]*/
1147-
{
1148-
Py_ssize_t i;
1149-
1150-
for (i = 0; i < Py_SIZE(self); i++) {
1149+
array_array_index_impl(arrayobject *self, PyObject *v, Py_ssize_t start,
1150+
Py_ssize_t stop)
1151+
/*[clinic end generated code: output=c45e777880c99f52 input=089dff7baa7e5a7e]*/
1152+
{
1153+
if (start < 0) {
1154+
start += Py_SIZE(self);
1155+
if (start < 0) {
1156+
start = 0;
1157+
}
1158+
}
1159+
if (stop < 0) {
1160+
stop += Py_SIZE(self);
1161+
}
1162+
// Use Py_SIZE() for every iteration in case the array is mutated
1163+
// during PyObject_RichCompareBool()
1164+
for (Py_ssize_t i = start; i < stop && i < Py_SIZE(self); i++) {
11511165
PyObject *selfi;
11521166
int cmp;
11531167

Modules/clinic/arraymodule.c.h

Lines changed: 41 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)