bpo-30537: use PyNumber in itertools.islice instead of PyLong (#1918)
authorWill Roberts <wildwilhelm@gmail.com>
Thu, 8 Jun 2017 06:03:04 +0000 (08:03 +0200)
committerRaymond Hettinger <rhettinger@users.noreply.github.com>
Thu, 8 Jun 2017 06:03:04 +0000 (23:03 -0700)
* bpo-30537: use PyNumber in itertools instead of PyLong

* bpo-30537: revert changes except to islice_new

* bpo-30537: test itertools.islice and add entry to Misc/NEWS

Lib/test/test_itertools.py
Misc/NEWS
Modules/itertoolsmodule.c

index f525255011459db28a985be450fb761600711057..50cf1488ec6184b24ff368a4c329ddf4ded6fc85 100644 (file)
@@ -1243,6 +1243,19 @@ class TestBasicOps(unittest.TestCase):
         support.gc_collect()
         self.assertIsNone(wr())
 
+        # Issue #30537: islice can accept integer-like objects as
+        # arguments
+        class IntLike(object):
+            def __init__(self, val):
+                self.val = val
+            def __index__(self):
+                return self.val
+        self.assertEqual(list(islice(range(100), IntLike(10))), list(range(10)))
+        self.assertEqual(list(islice(range(100), IntLike(10), IntLike(50))),
+                         list(range(10, 50)))
+        self.assertEqual(list(islice(range(100), IntLike(10), IntLike(50), IntLike(5))),
+                         list(range(10,50,5)))
+
     def test_takewhile(self):
         data = [1, 3, 5, 20, 2, 4, 6, 8]
         self.assertEqual(list(takewhile(underten, data)), [1, 3, 5])
index f043832e6703b7373788fc62207f208b0d7fe59b..0bc33bb2345d1f17043e4f3e39a2f37ef47909d8 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -128,6 +128,9 @@ Core and Builtins
 
 - bpo-29546: Improve from-import error message with location
 
+- bpo-30537: itertools.islice now accepts integer-like objects (having
+  an __index__ method) as start, stop, and slice arguments
+
 - Issue #29319: Prevent RunMainFromImporter overwriting sys.path[0].
 
 - Issue #29337: Fixed possible BytesWarning when compare the code objects.
index fac5b29a6acc22ed18e86c0f4e0718052e073399..ee7bb66fd19aa7a385359fb21c677f9335e6d16f 100644 (file)
@@ -1417,7 +1417,7 @@ islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
     numargs = PyTuple_Size(args);
     if (numargs == 2) {
         if (a1 != Py_None) {
-            stop = PyLong_AsSsize_t(a1);
+            stop = PyNumber_AsSsize_t(a1, PyExc_OverflowError);
             if (stop == -1) {
                 if (PyErr_Occurred())
                     PyErr_Clear();
@@ -1429,11 +1429,11 @@ islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
         }
     } else {
         if (a1 != Py_None)
-            start = PyLong_AsSsize_t(a1);
+            start = PyNumber_AsSsize_t(a1, PyExc_OverflowError);
         if (start == -1 && PyErr_Occurred())
             PyErr_Clear();
         if (a2 != Py_None) {
-            stop = PyLong_AsSsize_t(a2);
+            stop = PyNumber_AsSsize_t(a2, PyExc_OverflowError);
             if (stop == -1) {
                 if (PyErr_Occurred())
                     PyErr_Clear();
@@ -1453,7 +1453,7 @@ islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
     if (a3 != NULL) {
         if (a3 != Py_None)
-            step = PyLong_AsSsize_t(a3);
+            step = PyNumber_AsSsize_t(a3, PyExc_OverflowError);
         if (step == -1 && PyErr_Occurred())
             PyErr_Clear();
     }