Skip to content

Commit d4edfc9

Browse files
bpo-29935: Fixed error messages in the index() method of tuple, list and deque (#887)
when pass indices of wrong type.
1 parent 762ec97 commit d4edfc9

File tree

8 files changed

+31
-19
lines changed

8 files changed

+31
-19
lines changed

Include/ceval.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ PyAPI_FUNC(Py_ssize_t) _PyEval_RequestCodeExtraIndex(freefunc);
223223

224224
#ifndef Py_LIMITED_API
225225
PyAPI_FUNC(int) _PyEval_SliceIndex(PyObject *, Py_ssize_t *);
226-
PyAPI_FUNC(int) _PyEval_SliceIndexOrNone(PyObject *, Py_ssize_t *);
226+
PyAPI_FUNC(int) _PyEval_SliceIndexNotNone(PyObject *, Py_ssize_t *);
227227
PyAPI_FUNC(void) _PyEval_SignalAsyncExc(void);
228228
#endif
229229

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ What's New in Python 3.7.0 alpha 1?
1010
Core and Builtins
1111
-----------------
1212

13+
- bpo-29935: Fixed error messages in the index() method of tuple, list and deque
14+
when pass indices of wrong type.
15+
1316
- bpo-29816: Shift operation now has less opportunity to raise OverflowError.
1417
ValueError always is raised rather than OverflowError for negative counts.
1518
Shifting zero with non-negative count always returns zero.

Modules/_collectionsmodule.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,8 +1066,8 @@ deque_index(dequeobject *deque, PyObject **args, Py_ssize_t nargs,
10661066
return NULL;
10671067
}
10681068
if (!_PyArg_ParseStack(args, nargs, "O|O&O&:index", &v,
1069-
_PyEval_SliceIndex, &start,
1070-
_PyEval_SliceIndex, &stop)) {
1069+
_PyEval_SliceIndexNotNone, &start,
1070+
_PyEval_SliceIndexNotNone, &stop)) {
10711071
return NULL;
10721072
}
10731073

Objects/clinic/listobject.c.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ list_index(PyListObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwna
196196
Py_ssize_t stop = PY_SSIZE_T_MAX;
197197

198198
if (!_PyArg_ParseStack(args, nargs, "O|O&O&:index",
199-
&value, _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &stop)) {
199+
&value, _PyEval_SliceIndexNotNone, &start, _PyEval_SliceIndexNotNone, &stop)) {
200200
goto exit;
201201
}
202202

@@ -297,4 +297,4 @@ list___reversed__(PyListObject *self, PyObject *Py_UNUSED(ignored))
297297
{
298298
return list___reversed___impl(self);
299299
}
300-
/*[clinic end generated code: output=2a3b75efcf858ed5 input=a9049054013a1b77]*/
300+
/*[clinic end generated code: output=71deae70ca0e6799 input=a9049054013a1b77]*/

Objects/clinic/tupleobject.c.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ tuple_index(PyTupleObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kw
2626
Py_ssize_t stop = PY_SSIZE_T_MAX;
2727

2828
if (!_PyArg_ParseStack(args, nargs, "O|O&O&:index",
29-
&value, _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &stop)) {
29+
&value, _PyEval_SliceIndexNotNone, &start, _PyEval_SliceIndexNotNone, &stop)) {
3030
goto exit;
3131
}
3232

@@ -99,4 +99,4 @@ tuple___getnewargs__(PyTupleObject *self, PyObject *Py_UNUSED(ignored))
9999
{
100100
return tuple___getnewargs___impl(self);
101101
}
102-
/*[clinic end generated code: output=561a3654411d2225 input=a9049054013a1b77]*/
102+
/*[clinic end generated code: output=145bcfff64e8c809 input=a9049054013a1b77]*/

Objects/tupleobject.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -534,8 +534,8 @@ tuplerepeat(PyTupleObject *a, Py_ssize_t n)
534534
tuple.index
535535
536536
value: object
537-
start: object(converter="_PyEval_SliceIndex", type="Py_ssize_t") = 0
538-
stop: object(converter="_PyEval_SliceIndex", type="Py_ssize_t", c_default="PY_SSIZE_T_MAX") = sys.maxsize
537+
start: slice_index(accept={int}) = 0
538+
stop: slice_index(accept={int}, c_default="PY_SSIZE_T_MAX") = sys.maxsize
539539
/
540540
541541
Return first index of value.
@@ -546,7 +546,7 @@ Raises ValueError if the value is not present.
546546
static PyObject *
547547
tuple_index_impl(PyTupleObject *self, PyObject *value, Py_ssize_t start,
548548
Py_ssize_t stop)
549-
/*[clinic end generated code: output=07b6f9f3cb5c33eb input=28890d4bec234471]*/
549+
/*[clinic end generated code: output=07b6f9f3cb5c33eb input=fb39e9874a21fe3f]*/
550550
{
551551
Py_ssize_t i;
552552

Python/ceval.c

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4892,14 +4892,10 @@ do_call_core(PyObject *func, PyObject *callargs, PyObject *kwdict)
48924892
and silently boost values less than -PY_SSIZE_T_MAX-1 to -PY_SSIZE_T_MAX-1.
48934893
Return 0 on error, 1 on success.
48944894
*/
4895-
/* Note: If v is NULL, return success without storing into *pi. This
4896-
is because_PyEval_SliceIndex() is called by apply_slice(), which can be
4897-
called by the SLICE opcode with v and/or w equal to NULL.
4898-
*/
48994895
int
49004896
_PyEval_SliceIndex(PyObject *v, Py_ssize_t *pi)
49014897
{
4902-
if (v != NULL) {
4898+
if (v != Py_None) {
49034899
Py_ssize_t x;
49044900
if (PyIndex_Check(v)) {
49054901
x = PyNumber_AsSsize_t(v, NULL);
@@ -4918,9 +4914,22 @@ _PyEval_SliceIndex(PyObject *v, Py_ssize_t *pi)
49184914
}
49194915

49204916
int
4921-
_PyEval_SliceIndexOrNone(PyObject *v, Py_ssize_t *pi)
4917+
_PyEval_SliceIndexNotNone(PyObject *v, Py_ssize_t *pi)
49224918
{
4923-
return v == Py_None || _PyEval_SliceIndex(v, pi);
4919+
Py_ssize_t x;
4920+
if (PyIndex_Check(v)) {
4921+
x = PyNumber_AsSsize_t(v, NULL);
4922+
if (x == -1 && PyErr_Occurred())
4923+
return 0;
4924+
}
4925+
else {
4926+
PyErr_SetString(PyExc_TypeError,
4927+
"slice indices must be integers or "
4928+
"have an __index__ method");
4929+
return 0;
4930+
}
4931+
*pi = x;
4932+
return 1;
49244933
}
49254934

49264935

Tools/clinic/clinic.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2670,9 +2670,9 @@ class slice_index_converter(CConverter):
26702670

26712671
def converter_init(self, *, accept={int, NoneType}):
26722672
if accept == {int}:
2673-
self.converter = '_PyEval_SliceIndex'
2673+
self.converter = '_PyEval_SliceIndexNotNone'
26742674
elif accept == {int, NoneType}:
2675-
self.converter = '_PyEval_SliceIndexOrNone'
2675+
self.converter = '_PyEval_SliceIndex'
26762676
else:
26772677
fail("slice_index_converter: illegal 'accept' argument " + repr(accept))
26782678

0 commit comments

Comments
 (0)