bpo-29935: Fixed error messages in the index() method of tuple, list and deque (...
authorSerhiy Storchaka <storchaka@gmail.com>
Thu, 30 Mar 2017 15:29:23 +0000 (18:29 +0300)
committerGitHub <noreply@github.com>
Thu, 30 Mar 2017 15:29:23 +0000 (18:29 +0300)
when pass indices of wrong type.

Include/ceval.h
Misc/NEWS
Modules/_collectionsmodule.c
Objects/clinic/listobject.c.h
Objects/clinic/tupleobject.c.h
Objects/tupleobject.c
Python/ceval.c
Tools/clinic/clinic.py

index 25976bb37681ae7179f8e6f8522684a652e4c2fc..10be9d84eac83c09a0b0ee28df804ee911e09d2e 100644 (file)
@@ -223,7 +223,7 @@ PyAPI_FUNC(Py_ssize_t) _PyEval_RequestCodeExtraIndex(freefunc);
 
 #ifndef Py_LIMITED_API
 PyAPI_FUNC(int) _PyEval_SliceIndex(PyObject *, Py_ssize_t *);
-PyAPI_FUNC(int) _PyEval_SliceIndexOrNone(PyObject *, Py_ssize_t *);
+PyAPI_FUNC(int) _PyEval_SliceIndexNotNone(PyObject *, Py_ssize_t *);
 PyAPI_FUNC(void) _PyEval_SignalAsyncExc(void);
 #endif
 
index 87b47829d71ff623c1fd669b1404b29cef94e883..9c434a7735e5c5c81737280d1645c3f18d956a17 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,9 @@ What's New in Python 3.7.0 alpha 1?
 Core and Builtins
 -----------------
 
+- bpo-29935: Fixed error messages in the index() method of tuple, list and deque
+  when pass indices of wrong type.
+
 - bpo-29816: Shift operation now has less opportunity to raise OverflowError.
   ValueError always is raised rather than OverflowError for negative counts.
   Shifting zero with non-negative count always returns zero.
index b0525350cf1a1196bfc72a6c1749c7adbc57a2c7..6f78796fd904ddd322371f788947eac0f4fb7624 100644 (file)
@@ -1066,8 +1066,8 @@ deque_index(dequeobject *deque, PyObject **args, Py_ssize_t nargs,
         return NULL;
     }
     if (!_PyArg_ParseStack(args, nargs, "O|O&O&:index", &v,
-                           _PyEval_SliceIndex, &start,
-                           _PyEval_SliceIndex, &stop)) {
+                           _PyEval_SliceIndexNotNone, &start,
+                           _PyEval_SliceIndexNotNone, &stop)) {
         return NULL;
     }
 
index eeb932a240e536b9a575595f156642b29d2016e5..43d5599d7aae68cf2a51326166fdb867b863df9f 100644 (file)
@@ -196,7 +196,7 @@ list_index(PyListObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwna
     Py_ssize_t stop = PY_SSIZE_T_MAX;
 
     if (!_PyArg_ParseStack(args, nargs, "O|O&O&:index",
-        &value, _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &stop)) {
+        &value, _PyEval_SliceIndexNotNone, &start, _PyEval_SliceIndexNotNone, &stop)) {
         goto exit;
     }
 
@@ -297,4 +297,4 @@ list___reversed__(PyListObject *self, PyObject *Py_UNUSED(ignored))
 {
     return list___reversed___impl(self);
 }
-/*[clinic end generated code: output=2a3b75efcf858ed5 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=71deae70ca0e6799 input=a9049054013a1b77]*/
index 12f0df1d4393caab8915896d87ef4d9c58d95dfc..880b258dcaf5b01e3b542133c88bd009a235a4d1 100644 (file)
@@ -26,7 +26,7 @@ tuple_index(PyTupleObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kw
     Py_ssize_t stop = PY_SSIZE_T_MAX;
 
     if (!_PyArg_ParseStack(args, nargs, "O|O&O&:index",
-        &value, _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &stop)) {
+        &value, _PyEval_SliceIndexNotNone, &start, _PyEval_SliceIndexNotNone, &stop)) {
         goto exit;
     }
 
@@ -99,4 +99,4 @@ tuple___getnewargs__(PyTupleObject *self, PyObject *Py_UNUSED(ignored))
 {
     return tuple___getnewargs___impl(self);
 }
-/*[clinic end generated code: output=561a3654411d2225 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=145bcfff64e8c809 input=a9049054013a1b77]*/
index 9c63983d76492ad4d3871380ee5d47e5df6eb492..55da0e3a2bbff10caeed75d4d13c8cbde9ecc403 100644 (file)
@@ -534,8 +534,8 @@ tuplerepeat(PyTupleObject *a, Py_ssize_t n)
 tuple.index
 
     value: object
-    start: object(converter="_PyEval_SliceIndex", type="Py_ssize_t") = 0
-    stop: object(converter="_PyEval_SliceIndex", type="Py_ssize_t", c_default="PY_SSIZE_T_MAX") = sys.maxsize
+    start: slice_index(accept={int}) = 0
+    stop: slice_index(accept={int}, c_default="PY_SSIZE_T_MAX") = sys.maxsize
     /
 
 Return first index of value.
@@ -546,7 +546,7 @@ Raises ValueError if the value is not present.
 static PyObject *
 tuple_index_impl(PyTupleObject *self, PyObject *value, Py_ssize_t start,
                  Py_ssize_t stop)
-/*[clinic end generated code: output=07b6f9f3cb5c33eb input=28890d4bec234471]*/
+/*[clinic end generated code: output=07b6f9f3cb5c33eb input=fb39e9874a21fe3f]*/
 {
     Py_ssize_t i;
 
index e7ee772d9f67d12c799fec439b0f48a0b9424a92..afd305cf9af44ed0c6e7d4b54f05f25d820e26a4 100644 (file)
@@ -4892,14 +4892,10 @@ do_call_core(PyObject *func, PyObject *callargs, PyObject *kwdict)
    and silently boost values less than -PY_SSIZE_T_MAX-1 to -PY_SSIZE_T_MAX-1.
    Return 0 on error, 1 on success.
 */
-/* Note:  If v is NULL, return success without storing into *pi.  This
-   is because_PyEval_SliceIndex() is called by apply_slice(), which can be
-   called by the SLICE opcode with v and/or w equal to NULL.
-*/
 int
 _PyEval_SliceIndex(PyObject *v, Py_ssize_t *pi)
 {
-    if (v != NULL) {
+    if (v != Py_None) {
         Py_ssize_t x;
         if (PyIndex_Check(v)) {
             x = PyNumber_AsSsize_t(v, NULL);
@@ -4918,9 +4914,22 @@ _PyEval_SliceIndex(PyObject *v, Py_ssize_t *pi)
 }
 
 int
-_PyEval_SliceIndexOrNone(PyObject *v, Py_ssize_t *pi)
+_PyEval_SliceIndexNotNone(PyObject *v, Py_ssize_t *pi)
 {
-    return v == Py_None || _PyEval_SliceIndex(v, pi);
+    Py_ssize_t x;
+    if (PyIndex_Check(v)) {
+        x = PyNumber_AsSsize_t(v, NULL);
+        if (x == -1 && PyErr_Occurred())
+            return 0;
+    }
+    else {
+        PyErr_SetString(PyExc_TypeError,
+                        "slice indices must be integers or "
+                        "have an __index__ method");
+        return 0;
+    }
+    *pi = x;
+    return 1;
 }
 
 
index 1d570f17c354f9c7d1e0113f75da97ecb3344b28..6be0ab2b3d1527ffda2ac8c3c903b3fc59d57037 100755 (executable)
@@ -2670,9 +2670,9 @@ class slice_index_converter(CConverter):
 
     def converter_init(self, *, accept={int, NoneType}):
         if accept == {int}:
-            self.converter = '_PyEval_SliceIndex'
+            self.converter = '_PyEval_SliceIndexNotNone'
         elif accept == {int, NoneType}:
-            self.converter = '_PyEval_SliceIndexOrNone'
+            self.converter = '_PyEval_SliceIndex'
         else:
             fail("slice_index_converter: illegal 'accept' argument " + repr(accept))