8000 bpo-45018: Fix rangeiter_reduce in rangeobject.c (GH-27938) · python/cpython@cd986e9 · GitHub
[go: up one dir, main page]

Skip to content
< 8000 /react-partial>

Commit cd986e9

Browse files
bpo-45018: Fix rangeiter_reduce in rangeobject.c (GH-27938)
Co-authored-by: Łukasz Langa <lukasz@langa.pl> (cherry picked from commit 94a3d2a) Co-authored-by: chilaxan <chilaxan@gmail.com>
1 parent 8aa64cc commit cd986e9

File tree

3 files changed

+33
-17
lines changed

3 files changed

+33
-17
lines changed

Lib/test/test_range.py

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -374,26 +374,41 @@ def test_pickling(self):
374374
list(r))
375375

376376
def test_iterator_pickling(self):
377-
testcases = [(13,), (0, 11), (-22, 10), (20, 3, -1),
378-
(13, 21, 3), (-2, 2, 2), (2**65, 2**65+2)]
377+
testcases = [(13,), (0, 11), (-22, 10), (20, 3, -1), (13, 21, 3),
378+
(-2, 2, 2), (2**31-3, 2**31-1), (2**33, 2**33+2),
379+
(2**63-3, 2**63-1), (2**65, 2**65+2)]
379380
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
380381
for t in testcases:
381-
it = itorg = iter(range(*t))
382-
data = list(range(*t))
383-
384-
d = pickle.dumps(it, proto)
385-
it = pickle.loads(d)
386-
self.assertEqual(type(itorg), type(it))
387-
self.assertEqual(list(it), data)
388-
389-
it = pickle.loads(d)
390-
try:
391-
next(it)
392 10000 -
except StopIteration:
393-
continue
382+
with self.subTest(proto=proto, t=t):
383+
it = itorg = iter(range(*t))
384+
data = list(range(*t))
385+
386+
d = pickle.dumps(it, proto)
387+
it = pickle.loads(d)
388+
self.assertEqual(type(itorg), type(it))
389+
self.assertEqual(list(it), data)
390+
391+
it = pickle.loads(d)
392+
try:
393+
next(it)
394+
except StopIteration:
395+
continue
396+
d = pickle.dumps(it, proto)
397+
it = pickle.loads(d)
398+
self.assertEqual(list(it), data[1:])
399+
400+
def test_iterator_pickling_overflowing_index(self):
401+
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
402+
with self.subTest(proto=proto):
403+
it = iter(range(2**32 + 2))
404+
_, _, idx = it.__reduce__()
405+
self.assertEqual(idx, 0)
406+
it.__setstate__(2**32 + 1) # undocumented way to set r->index
407+
_, _, idx = it.__reduce__()
408+
self.assertEqual(idx, 2**32 + 1)
394409
d = pickle.dumps(it, proto)
395410
it = pickle.loads(d)
396-
self.assertEqual(list(it), data[1:])
411+
self.assertEqual(next(it), 2**32 + 1)
397412

398413
def test_exhausted_iterator_pickling(self):
399414
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixed pickling of range iterators that iterated for over 2**32 times.

Objects/rangeobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -813,7 +813,7 @@ rangeiter_reduce(rangeiterobject *r, PyObject *Py_UNUSED(ignored))
813813
if (range == NULL)
814814
goto err;
815815
/* return the result */
816-
return Py_BuildValue("N(N)i", _PyEval_GetBuiltinId(&PyId_iter),
816+
return Py_BuildValue("N(N)l", _PyEval_GetBuiltinId(&PyId_iter),
817817
range, r->index);
818818
err:
819819
Py_XDECREF(start);

0 commit comments

Comments
 (0)
0