mirror of
https://github.com/python/cpython.git
synced 2025-08-14 05:52:50 +00:00
[3.12] GH-101588: Deprecate pickle/copy/deepcopy support in itertools (GH-104965) (GH-104997)
This commit is contained in:
parent
305d78b714
commit
05189f3054
4 changed files with 97 additions and 3 deletions
|
@ -1069,6 +1069,12 @@ Pending Removal in Python 3.14
|
||||||
functions that have been deprecated since Python 2 but only gained a
|
functions that have been deprecated since Python 2 but only gained a
|
||||||
proper :exc:`DeprecationWarning` in 3.12. Remove them in 3.14.
|
proper :exc:`DeprecationWarning` in 3.12. Remove them in 3.14.
|
||||||
|
|
||||||
|
* :mod:`itertools` had undocumented, inefficient, historically buggy,
|
||||||
|
and inconsistent support for copy, deepcopy, and pickle operations.
|
||||||
|
This will be removed in 3.14 for a significant reduction in code
|
||||||
|
volume and maintenance burden.
|
||||||
|
(Contributed by Raymond Hettinger in :gh:`101588`.)
|
||||||
|
|
||||||
* Accessing ``co_lnotab`` was deprecated in :pep:`626` since 3.10
|
* Accessing ``co_lnotab`` was deprecated in :pep:`626` since 3.10
|
||||||
and was planned to be removed in 3.12
|
and was planned to be removed in 3.12
|
||||||
but it only got a proper :exc:`DeprecationWarning` in 3.12.
|
but it only got a proper :exc:`DeprecationWarning` in 3.12.
|
||||||
|
|
|
@ -15,6 +15,26 @@ import sys
|
||||||
import struct
|
import struct
|
||||||
import threading
|
import threading
|
||||||
import gc
|
import gc
|
||||||
|
import warnings
|
||||||
|
|
||||||
|
def pickle_deprecated(testfunc):
|
||||||
|
""" Run the test three times.
|
||||||
|
First, verify that a Deprecation Warning is raised.
|
||||||
|
Second, run normally but with DeprecationWarnings temporarily disabled.
|
||||||
|
Third, run with warnings promoted to errors.
|
||||||
|
"""
|
||||||
|
def inner(self):
|
||||||
|
with self.assertWarns(DeprecationWarning):
|
||||||
|
testfunc(self)
|
||||||
|
with warnings.catch_warnings():
|
||||||
|
warnings.simplefilter("ignore", category=DeprecationWarning)
|
||||||
|
testfunc(self)
|
||||||
|
with warnings.catch_warnings():
|
||||||
|
warnings.simplefilter("error", category=DeprecationWarning)
|
||||||
|
with self.assertRaises((DeprecationWarning, AssertionError, SystemError)):
|
||||||
|
testfunc(self)
|
||||||
|
|
||||||
|
return inner
|
||||||
|
|
||||||
maxsize = support.MAX_Py_ssize_t
|
maxsize = support.MAX_Py_ssize_t
|
||||||
minsize = -maxsize-1
|
minsize = -maxsize-1
|
||||||
|
@ -124,6 +144,7 @@ class TestBasicOps(unittest.TestCase):
|
||||||
c = expand(compare[took:])
|
c = expand(compare[took:])
|
||||||
self.assertEqual(a, c);
|
self.assertEqual(a, c);
|
||||||
|
|
||||||
|
@pickle_deprecated
|
||||||
def test_accumulate(self):
|
def test_accumulate(self):
|
||||||
self.assertEqual(list(accumulate(range(10))), # one positional arg
|
self.assertEqual(list(accumulate(range(10))), # one positional arg
|
||||||
[0, 1, 3, 6, 10, 15, 21, 28, 36, 45])
|
[0, 1, 3, 6, 10, 15, 21, 28, 36, 45])
|
||||||
|
@ -220,6 +241,7 @@ class TestBasicOps(unittest.TestCase):
|
||||||
self.assertRaises(TypeError, list, chain.from_iterable([2, 3]))
|
self.assertRaises(TypeError, list, chain.from_iterable([2, 3]))
|
||||||
self.assertEqual(list(islice(chain.from_iterable(repeat(range(5))), 2)), [0, 1])
|
self.assertEqual(list(islice(chain.from_iterable(repeat(range(5))), 2)), [0, 1])
|
||||||
|
|
||||||
|
@pickle_deprecated
|
||||||
def test_chain_reducible(self):
|
def test_chain_reducible(self):
|
||||||
for oper in [copy.deepcopy] + picklecopiers:
|
for oper in [copy.deepcopy] + picklecopiers:
|
||||||
it = chain('abc', 'def')
|
it = chain('abc', 'def')
|
||||||
|
@ -233,6 +255,7 @@ class TestBasicOps(unittest.TestCase):
|
||||||
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
|
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
|
||||||
self.pickletest(proto, chain('abc', 'def'), compare=list('abcdef'))
|
self.pickletest(proto, chain('abc', 'def'), compare=list('abcdef'))
|
||||||
|
|
||||||
|
@pickle_deprecated
|
||||||
def test_chain_setstate(self):
|
def test_chain_setstate(self):
|
||||||
self.assertRaises(TypeError, chain().__setstate__, ())
|
self.assertRaises(TypeError, chain().__setstate__, ())
|
||||||
self.assertRaises(TypeError, chain().__setstate__, [])
|
self.assertRaises(TypeError, chain().__setstate__, [])
|
||||||
|
@ -246,6 +269,7 @@ class TestBasicOps(unittest.TestCase):
|
||||||
it.__setstate__((iter(['abc', 'def']), iter(['ghi'])))
|
it.__setstate__((iter(['abc', 'def']), iter(['ghi'])))
|
||||||
self.assertEqual(list(it), ['ghi', 'a', 'b', 'c', 'd', 'e', 'f'])
|
self.assertEqual(list(it), ['ghi', 'a', 'b', 'c', 'd', 'e', 'f'])
|
||||||
|
|
||||||
|
@pickle_deprecated
|
||||||
def test_combinations(self):
|
def test_combinations(self):
|
||||||
self.assertRaises(TypeError, combinations, 'abc') # missing r argument
|
self.assertRaises(TypeError, combinations, 'abc') # missing r argument
|
||||||
self.assertRaises(TypeError, combinations, 'abc', 2, 1) # too many arguments
|
self.assertRaises(TypeError, combinations, 'abc', 2, 1) # too many arguments
|
||||||
|
@ -269,7 +293,6 @@ class TestBasicOps(unittest.TestCase):
|
||||||
self.assertEqual(list(op(testIntermediate)),
|
self.assertEqual(list(op(testIntermediate)),
|
||||||
[(0,1,3), (0,2,3), (1,2,3)])
|
[(0,1,3), (0,2,3), (1,2,3)])
|
||||||
|
|
||||||
|
|
||||||
def combinations1(iterable, r):
|
def combinations1(iterable, r):
|
||||||
'Pure python version shown in the docs'
|
'Pure python version shown in the docs'
|
||||||
pool = tuple(iterable)
|
pool = tuple(iterable)
|
||||||
|
@ -337,6 +360,7 @@ class TestBasicOps(unittest.TestCase):
|
||||||
self.assertEqual(len(set(map(id, combinations('abcde', 3)))), 1)
|
self.assertEqual(len(set(map(id, combinations('abcde', 3)))), 1)
|
||||||
self.assertNotEqual(len(set(map(id, list(combinations('abcde', 3))))), 1)
|
self.assertNotEqual(len(set(map(id, list(combinations('abcde', 3))))), 1)
|
||||||
|
|
||||||
|
@pickle_deprecated
|
||||||
def test_combinations_with_replacement(self):
|
def test_combinations_with_replacement(self):
|
||||||
cwr = combinations_with_replacement
|
cwr = combinations_with_replacement
|
||||||
self.assertRaises(TypeError, cwr, 'abc') # missing r argument
|
self.assertRaises(TypeError, cwr, 'abc') # missing r argument
|
||||||
|
@ -425,6 +449,7 @@ class TestBasicOps(unittest.TestCase):
|
||||||
self.assertEqual(len(set(map(id, cwr('abcde', 3)))), 1)
|
self.assertEqual(len(set(map(id, cwr('abcde', 3)))), 1)
|
||||||
self.assertNotEqual(len(set(map(id, list(cwr('abcde', 3))))), 1)
|
self.assertNotEqual(len(set(map(id, list(cwr('abcde', 3))))), 1)
|
||||||
|
|
||||||
|
@pickle_deprecated
|
||||||
def test_permutations(self):
|
def test_permutations(self):
|
||||||
self.assertRaises(TypeError, permutations) # too few arguments
|
self.assertRaises(TypeError, permutations) # too few arguments
|
||||||
self.assertRaises(TypeError, permutations, 'abc', 2, 1) # too many arguments
|
self.assertRaises(TypeError, permutations, 'abc', 2, 1) # too many arguments
|
||||||
|
@ -531,6 +556,7 @@ class TestBasicOps(unittest.TestCase):
|
||||||
self.assertEqual(comb, list(filter(set(perm).__contains__, cwr))) # comb: cwr that is a perm
|
self.assertEqual(comb, list(filter(set(perm).__contains__, cwr))) # comb: cwr that is a perm
|
||||||
self.assertEqual(comb, sorted(set(cwr) & set(perm))) # comb: both a cwr and a perm
|
self.assertEqual(comb, sorted(set(cwr) & set(perm))) # comb: both a cwr and a perm
|
||||||
|
|
||||||
|
@pickle_deprecated
|
||||||
def test_compress(self):
|
def test_compress(self):
|
||||||
self.assertEqual(list(compress(data='ABCDEF', selectors=[1,0,1,0,1,1])), list('ACEF'))
|
self.assertEqual(list(compress(data='ABCDEF', selectors=[1,0,1,0,1,1])), list('ACEF'))
|
||||||
self.assertEqual(list(compress('ABCDEF', [1,0,1,0,1,1])), list('ACEF'))
|
self.assertEqual(list(compress('ABCDEF', [1,0,1,0,1,1])), list('ACEF'))
|
||||||
|
@ -564,7 +590,7 @@ class TestBasicOps(unittest.TestCase):
|
||||||
next(testIntermediate)
|
next(testIntermediate)
|
||||||
self.assertEqual(list(op(testIntermediate)), list(result2))
|
self.assertEqual(list(op(testIntermediate)), list(result2))
|
||||||
|
|
||||||
|
@pickle_deprecated
|
||||||
def test_count(self):
|
def test_count(self):
|
||||||
self.assertEqual(lzip('abc',count()), [('a', 0), ('b', 1), ('c', 2)])
|
self.assertEqual(lzip('abc',count()), [('a', 0), ('b', 1), ('c', 2)])
|
||||||
self.assertEqual(lzip('abc',count(3)), [('a', 3), ('b', 4), ('c', 5)])
|
self.assertEqual(lzip('abc',count(3)), [('a', 3), ('b', 4), ('c', 5)])
|
||||||
|
@ -613,6 +639,7 @@ class TestBasicOps(unittest.TestCase):
|
||||||
#check proper internal error handling for large "step' sizes
|
#check proper internal error handling for large "step' sizes
|
||||||
count(1, maxsize+5); sys.exc_info()
|
count(1, maxsize+5); sys.exc_info()
|
||||||
|
|
||||||
|
@pickle_deprecated
|
||||||
def test_count_with_stride(self):
|
def test_count_with_stride(self):
|
||||||
self.assertEqual(lzip('abc',count(2,3)), [('a', 2), ('b', 5), ('c', 8)])
|
self.assertEqual(lzip('abc',count(2,3)), [('a', 2), ('b', 5), ('c', 8)])
|
||||||
self.assertEqual(lzip('abc',count(start=2,step=3)),
|
self.assertEqual(lzip('abc',count(start=2,step=3)),
|
||||||
|
@ -675,6 +702,7 @@ class TestBasicOps(unittest.TestCase):
|
||||||
self.assertRaises(TypeError, cycle, 5)
|
self.assertRaises(TypeError, cycle, 5)
|
||||||
self.assertEqual(list(islice(cycle(gen3()),10)), [0,1,2,0,1,2,0,1,2,0])
|
self.assertEqual(list(islice(cycle(gen3()),10)), [0,1,2,0,1,2,0,1,2,0])
|
||||||
|
|
||||||
|
@pickle_deprecated
|
||||||
def test_cycle_copy_pickle(self):
|
def test_cycle_copy_pickle(self):
|
||||||
# check copy, deepcopy, pickle
|
# check copy, deepcopy, pickle
|
||||||
c = cycle('abc')
|
c = cycle('abc')
|
||||||
|
@ -711,6 +739,7 @@ class TestBasicOps(unittest.TestCase):
|
||||||
d = pickle.loads(p) # rebuild the cycle object
|
d = pickle.loads(p) # rebuild the cycle object
|
||||||
self.assertEqual(take(20, d), list('cdeabcdeabcdeabcdeab'))
|
self.assertEqual(take(20, d), list('cdeabcdeabcdeabcdeab'))
|
||||||
|
|
||||||
|
@pickle_deprecated
|
||||||
def test_cycle_unpickle_compat(self):
|
def test_cycle_unpickle_compat(self):
|
||||||
testcases = [
|
testcases = [
|
||||||
b'citertools\ncycle\n(c__builtin__\niter\n((lI1\naI2\naI3\natRI1\nbtR((lI1\naI0\ntb.',
|
b'citertools\ncycle\n(c__builtin__\niter\n((lI1\naI2\naI3\natRI1\nbtR((lI1\naI0\ntb.',
|
||||||
|
@ -742,6 +771,7 @@ class TestBasicOps(unittest.TestCase):
|
||||||
it = pickle.loads(t)
|
it = pickle.loads(t)
|
||||||
self.assertEqual(take(10, it), [2, 3, 1, 2, 3, 1, 2, 3, 1, 2])
|
self.assertEqual(take(10, it), [2, 3, 1, 2, 3, 1, 2, 3, 1, 2])
|
||||||
|
|
||||||
|
@pickle_deprecated
|
||||||
def test_cycle_setstate(self):
|
def test_cycle_setstate(self):
|
||||||
# Verify both modes for restoring state
|
# Verify both modes for restoring state
|
||||||
|
|
||||||
|
@ -778,6 +808,7 @@ class TestBasicOps(unittest.TestCase):
|
||||||
self.assertRaises(TypeError, cycle('').__setstate__, ())
|
self.assertRaises(TypeError, cycle('').__setstate__, ())
|
||||||
self.assertRaises(TypeError, cycle('').__setstate__, ([],))
|
self.assertRaises(TypeError, cycle('').__setstate__, ([],))
|
||||||
|
|
||||||
|
@pickle_deprecated
|
||||||
def test_groupby(self):
|
def test_groupby(self):
|
||||||
# Check whether it accepts arguments correctly
|
# Check whether it accepts arguments correctly
|
||||||
self.assertEqual([], list(groupby([])))
|
self.assertEqual([], list(groupby([])))
|
||||||
|
@ -935,6 +966,7 @@ class TestBasicOps(unittest.TestCase):
|
||||||
c = filter(isEven, range(6))
|
c = filter(isEven, range(6))
|
||||||
self.pickletest(proto, c)
|
self.pickletest(proto, c)
|
||||||
|
|
||||||
|
@pickle_deprecated
|
||||||
def test_filterfalse(self):
|
def test_filterfalse(self):
|
||||||
self.assertEqual(list(filterfalse(isEven, range(6))), [1,3,5])
|
self.assertEqual(list(filterfalse(isEven, range(6))), [1,3,5])
|
||||||
self.assertEqual(list(filterfalse(None, [0,1,0,2,0])), [0,0,0])
|
self.assertEqual(list(filterfalse(None, [0,1,0,2,0])), [0,0,0])
|
||||||
|
@ -965,6 +997,7 @@ class TestBasicOps(unittest.TestCase):
|
||||||
lzip('abc', 'def'))
|
lzip('abc', 'def'))
|
||||||
|
|
||||||
@support.impl_detail("tuple reuse is specific to CPython")
|
@support.impl_detail("tuple reuse is specific to CPython")
|
||||||
|
@pickle_deprecated
|
||||||
def test_zip_tuple_reuse(self):
|
def test_zip_tuple_reuse(self):
|
||||||
ids = list(map(id, zip('abc', 'def')))
|
ids = list(map(id, zip('abc', 'def')))
|
||||||
self.assertEqual(min(ids), max(ids))
|
self.assertEqual(min(ids), max(ids))
|
||||||
|
@ -1040,6 +1073,7 @@ class TestBasicOps(unittest.TestCase):
|
||||||
ids = list(map(id, list(zip_longest('abc', 'def'))))
|
ids = list(map(id, list(zip_longest('abc', 'def'))))
|
||||||
self.assertEqual(len(dict.fromkeys(ids)), len(ids))
|
self.assertEqual(len(dict.fromkeys(ids)), len(ids))
|
||||||
|
|
||||||
|
@pickle_deprecated
|
||||||
def test_zip_longest_pickling(self):
|
def test_zip_longest_pickling(self):
|
||||||
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
|
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
|
||||||
self.pickletest(proto, zip_longest("abc", "def"))
|
self.pickletest(proto, zip_longest("abc", "def"))
|
||||||
|
@ -1186,6 +1220,7 @@ class TestBasicOps(unittest.TestCase):
|
||||||
self.assertEqual(len(set(map(id, product('abc', 'def')))), 1)
|
self.assertEqual(len(set(map(id, product('abc', 'def')))), 1)
|
||||||
self.assertNotEqual(len(set(map(id, list(product('abc', 'def'))))), 1)
|
self.assertNotEqual(len(set(map(id, list(product('abc', 'def'))))), 1)
|
||||||
|
|
||||||
|
@pickle_deprecated
|
||||||
def test_product_pickling(self):
|
def test_product_pickling(self):
|
||||||
# check copy, deepcopy, pickle
|
# check copy, deepcopy, pickle
|
||||||
for args, result in [
|
for args, result in [
|
||||||
|
@ -1201,6 +1236,7 @@ class TestBasicOps(unittest.TestCase):
|
||||||
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
|
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
|
||||||
self.pickletest(proto, product(*args))
|
self.pickletest(proto, product(*args))
|
||||||
|
|
||||||
|
@pickle_deprecated
|
||||||
def test_product_issue_25021(self):
|
def test_product_issue_25021(self):
|
||||||
# test that indices are properly clamped to the length of the tuples
|
# test that indices are properly clamped to the length of the tuples
|
||||||
p = product((1, 2),(3,))
|
p = product((1, 2),(3,))
|
||||||
|
@ -1211,6 +1247,7 @@ class TestBasicOps(unittest.TestCase):
|
||||||
p.__setstate__((0, 0, 0x1000)) # will access tuple element 1 if not clamped
|
p.__setstate__((0, 0, 0x1000)) # will access tuple element 1 if not clamped
|
||||||
self.assertRaises(StopIteration, next, p)
|
self.assertRaises(StopIteration, next, p)
|
||||||
|
|
||||||
|
@pickle_deprecated
|
||||||
def test_repeat(self):
|
def test_repeat(self):
|
||||||
self.assertEqual(list(repeat(object='a', times=3)), ['a', 'a', 'a'])
|
self.assertEqual(list(repeat(object='a', times=3)), ['a', 'a', 'a'])
|
||||||
self.assertEqual(lzip(range(3),repeat('a')),
|
self.assertEqual(lzip(range(3),repeat('a')),
|
||||||
|
@ -1243,6 +1280,7 @@ class TestBasicOps(unittest.TestCase):
|
||||||
self.assertEqual(repr(repeat('a', times=-1)), "repeat('a', 0)")
|
self.assertEqual(repr(repeat('a', times=-1)), "repeat('a', 0)")
|
||||||
self.assertEqual(repr(repeat('a', times=-2)), "repeat('a', 0)")
|
self.assertEqual(repr(repeat('a', times=-2)), "repeat('a', 0)")
|
||||||
|
|
||||||
|
@pickle_deprecated
|
||||||
def test_map(self):
|
def test_map(self):
|
||||||
self.assertEqual(list(map(operator.pow, range(3), range(1,7))),
|
self.assertEqual(list(map(operator.pow, range(3), range(1,7))),
|
||||||
[0**1, 1**2, 2**3])
|
[0**1, 1**2, 2**3])
|
||||||
|
@ -1273,6 +1311,7 @@ class TestBasicOps(unittest.TestCase):
|
||||||
c = map(tupleize, 'abc', count())
|
c = map(tupleize, 'abc', count())
|
||||||
self.pickletest(proto, c)
|
self.pickletest(proto, c)
|
||||||
|
|
||||||
|
@pickle_deprecated
|
||||||
def test_starmap(self):
|
def test_starmap(self):
|
||||||
self.assertEqual(list(starmap(operator.pow, zip(range(3), range(1,7)))),
|
self.assertEqual(list(starmap(operator.pow, zip(range(3), range(1,7)))),
|
||||||
[0**1, 1**2, 2**3])
|
[0**1, 1**2, 2**3])
|
||||||
|
@ -1300,6 +1339,7 @@ class TestBasicOps(unittest.TestCase):
|
||||||
c = starmap(operator.pow, zip(range(3), range(1,7)))
|
c = starmap(operator.pow, zip(range(3), range(1,7)))
|
||||||
self.pickletest(proto, c)
|
self.pickletest(proto, c)
|
||||||
|
|
||||||
|
@pickle_deprecated
|
||||||
def test_islice(self):
|
def test_islice(self):
|
||||||
for args in [ # islice(args) should agree with range(args)
|
for args in [ # islice(args) should agree with range(args)
|
||||||
(10, 20, 3),
|
(10, 20, 3),
|
||||||
|
@ -1394,6 +1434,7 @@ class TestBasicOps(unittest.TestCase):
|
||||||
self.assertEqual(list(islice(range(100), IntLike(10), IntLike(50), IntLike(5))),
|
self.assertEqual(list(islice(range(100), IntLike(10), IntLike(50), IntLike(5))),
|
||||||
list(range(10,50,5)))
|
list(range(10,50,5)))
|
||||||
|
|
||||||
|
@pickle_deprecated
|
||||||
def test_takewhile(self):
|
def test_takewhile(self):
|
||||||
data = [1, 3, 5, 20, 2, 4, 6, 8]
|
data = [1, 3, 5, 20, 2, 4, 6, 8]
|
||||||
self.assertEqual(list(takewhile(underten, data)), [1, 3, 5])
|
self.assertEqual(list(takewhile(underten, data)), [1, 3, 5])
|
||||||
|
@ -1414,6 +1455,7 @@ class TestBasicOps(unittest.TestCase):
|
||||||
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
|
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
|
||||||
self.pickletest(proto, takewhile(underten, data))
|
self.pickletest(proto, takewhile(underten, data))
|
||||||
|
|
||||||
|
@pickle_deprecated
|
||||||
def test_dropwhile(self):
|
def test_dropwhile(self):
|
||||||
data = [1, 3, 5, 20, 2, 4, 6, 8]
|
data = [1, 3, 5, 20, 2, 4, 6, 8]
|
||||||
self.assertEqual(list(dropwhile(underten, data)), [20, 2, 4, 6, 8])
|
self.assertEqual(list(dropwhile(underten, data)), [20, 2, 4, 6, 8])
|
||||||
|
@ -1431,6 +1473,7 @@ class TestBasicOps(unittest.TestCase):
|
||||||
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
|
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
|
||||||
self.pickletest(proto, dropwhile(underten, data))
|
self.pickletest(proto, dropwhile(underten, data))
|
||||||
|
|
||||||
|
@pickle_deprecated
|
||||||
def test_tee(self):
|
def test_tee(self):
|
||||||
n = 200
|
n = 200
|
||||||
|
|
||||||
|
@ -1732,6 +1775,7 @@ class TestExamples(unittest.TestCase):
|
||||||
def test_accumulate(self):
|
def test_accumulate(self):
|
||||||
self.assertEqual(list(accumulate([1,2,3,4,5])), [1, 3, 6, 10, 15])
|
self.assertEqual(list(accumulate([1,2,3,4,5])), [1, 3, 6, 10, 15])
|
||||||
|
|
||||||
|
@pickle_deprecated
|
||||||
def test_accumulate_reducible(self):
|
def test_accumulate_reducible(self):
|
||||||
# check copy, deepcopy, pickle
|
# check copy, deepcopy, pickle
|
||||||
data = [1, 2, 3, 4, 5]
|
data = [1, 2, 3, 4, 5]
|
||||||
|
@ -1747,6 +1791,7 @@ class TestExamples(unittest.TestCase):
|
||||||
self.assertEqual(list(copy.deepcopy(it)), accumulated[1:])
|
self.assertEqual(list(copy.deepcopy(it)), accumulated[1:])
|
||||||
self.assertEqual(list(copy.copy(it)), accumulated[1:])
|
self.assertEqual(list(copy.copy(it)), accumulated[1:])
|
||||||
|
|
||||||
|
@pickle_deprecated
|
||||||
def test_accumulate_reducible_none(self):
|
def test_accumulate_reducible_none(self):
|
||||||
# Issue #25718: total is None
|
# Issue #25718: total is None
|
||||||
it = accumulate([None, None, None], operator.is_)
|
it = accumulate([None, None, None], operator.is_)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Deprecate undocumented copy/deepcopy/pickle support for itertools.
|
|
@ -93,6 +93,16 @@ class itertools.pairwise "pairwiseobject *" "clinic_state()->pairwise_type"
|
||||||
#undef clinic_state_by_cls
|
#undef clinic_state_by_cls
|
||||||
#undef clinic_state
|
#undef clinic_state
|
||||||
|
|
||||||
|
/* Deprecation of pickle support: GH-101588 *********************************/
|
||||||
|
|
||||||
|
#define ITERTOOL_PICKLE_DEPRECATION \
|
||||||
|
if (PyErr_WarnEx( \
|
||||||
|
PyExc_DeprecationWarning, \
|
||||||
|
"Itertool pickle/copy/deepcopy support " \
|
||||||
|
"will be removed in a Python 3.14.", 1) < 0) { \
|
||||||
|
return NULL; \
|
||||||
|
}
|
||||||
|
|
||||||
/* batched object ************************************************************/
|
/* batched object ************************************************************/
|
||||||
|
|
||||||
/* Note: The built-in zip() function includes a "strict" argument
|
/* Note: The built-in zip() function includes a "strict" argument
|
||||||
|
@ -506,6 +516,7 @@ groupby_reduce(groupbyobject *lz, PyObject *Py_UNUSED(ignored))
|
||||||
/* reduce as a 'new' call with an optional 'setstate' if groupby
|
/* reduce as a 'new' call with an optional 'setstate' if groupby
|
||||||
* has started
|
* has started
|
||||||
*/
|
*/
|
||||||
|
ITERTOOL_PICKLE_DEPRECATION;
|
||||||
PyObject *value;
|
PyObject *value;
|
||||||
if (lz->tgtkey && lz->currkey && lz->currvalue)
|
if (lz->tgtkey && lz->currkey && lz->currvalue)
|
||||||
value = Py_BuildValue("O(OO)(OOO)", Py_TYPE(lz),
|
value = Py_BuildValue("O(OO)(OOO)", Py_TYPE(lz),
|
||||||
|
@ -522,6 +533,7 @@ PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
|
||||||
static PyObject *
|
static PyObject *
|
||||||
groupby_setstate(groupbyobject *lz, PyObject *state)
|
groupby_setstate(groupbyobject *lz, PyObject *state)
|
||||||
{
|
{
|
||||||
|
ITERTOOL_PICKLE_DEPRECATION;
|
||||||
PyObject *currkey, *currvalue, *tgtkey;
|
PyObject *currkey, *currvalue, *tgtkey;
|
||||||
if (!PyTuple_Check(state)) {
|
if (!PyTuple_Check(state)) {
|
||||||
PyErr_SetString(PyExc_TypeError, "state is not a tuple");
|
PyErr_SetString(PyExc_TypeError, "state is not a tuple");
|
||||||
|
@ -660,6 +672,7 @@ _grouper_next(_grouperobject *igo)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_grouper_reduce(_grouperobject *lz, PyObject *Py_UNUSED(ignored))
|
_grouper_reduce(_grouperobject *lz, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
ITERTOOL_PICKLE_DEPRECATION;
|
||||||
if (((groupbyobject *)lz->parent)->currgrouper != lz) {
|
if (((groupbyobject *)lz->parent)->currgrouper != lz) {
|
||||||
return Py_BuildValue("N(())", _PyEval_GetBuiltin(&_Py_ID(iter)));
|
return Py_BuildValue("N(())", _PyEval_GetBuiltin(&_Py_ID(iter)));
|
||||||
}
|
}
|
||||||
|
@ -828,6 +841,7 @@ teedataobject_dealloc(teedataobject *tdo)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
teedataobject_reduce(teedataobject *tdo, PyObject *Py_UNUSED(ignored))
|
teedataobject_reduce(teedataobject *tdo, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
ITERTOOL_PICKLE_DEPRECATION;
|
||||||
int i;
|
int i;
|
||||||
/* create a temporary list of already iterated values */
|
/* create a temporary list of already iterated values */
|
||||||
PyObject *values = PyList_New(tdo->numread);
|
PyObject *values = PyList_New(tdo->numread);
|
||||||
|
@ -1041,12 +1055,14 @@ tee_dealloc(teeobject *to)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
tee_reduce(teeobject *to, PyObject *Py_UNUSED(ignored))
|
tee_reduce(teeobject *to, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
ITERTOOL_PICKLE_DEPRECATION;
|
||||||
return Py_BuildValue("O(())(Oi)", Py_TYPE(to), to->dataobj, to->index);
|
return Py_BuildValue("O(())(Oi)", Py_TYPE(to), to->dataobj, to->index);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
tee_setstate(teeobject *to, PyObject *state)
|
tee_setstate(teeobject *to, PyObject *state)
|
||||||
{
|
{
|
||||||
|
ITERTOOL_PICKLE_DEPRECATION;
|
||||||
teedataobject *tdo;
|
teedataobject *tdo;
|
||||||
int index;
|
int index;
|
||||||
if (!PyTuple_Check(state)) {
|
if (!PyTuple_Check(state)) {
|
||||||
|
@ -1275,6 +1291,7 @@ cycle_next(cycleobject *lz)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
cycle_reduce(cycleobject *lz, PyObject *Py_UNUSED(ignored))
|
cycle_reduce(cycleobject *lz, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
ITERTOOL_PICKLE_DEPRECATION;
|
||||||
/* Create a new cycle with the iterator tuple, then set the saved state */
|
/* Create a new cycle with the iterator tuple, then set the saved state */
|
||||||
if (lz->it == NULL) {
|
if (lz->it == NULL) {
|
||||||
PyObject *it = PyObject_GetIter(lz->saved);
|
PyObject *it = PyObject_GetIter(lz->saved);
|
||||||
|
@ -1298,6 +1315,7 @@ cycle_reduce(cycleobject *lz, PyObject *Py_UNUSED(ignored))
|
||||||
static PyObject *
|
static PyObject *
|
||||||
cycle_setstate(cycleobject *lz, PyObject *state)
|
cycle_setstate(cycleobject *lz, PyObject *state)
|
||||||
{
|
{
|
||||||
|
ITERTOOL_PICKLE_DEPRECATION;
|
||||||
PyObject *saved=NULL;
|
PyObject *saved=NULL;
|
||||||
int firstpass;
|
int firstpass;
|
||||||
if (!PyTuple_Check(state)) {
|
if (!PyTuple_Check(state)) {
|
||||||
|
@ -1446,12 +1464,14 @@ dropwhile_next(dropwhileobject *lz)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
dropwhile_reduce(dropwhileobject *lz, PyObject *Py_UNUSED(ignored))
|
dropwhile_reduce(dropwhileobject *lz, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
ITERTOOL_PICKLE_DEPRECATION;
|
||||||
return Py_BuildValue("O(OO)l", Py_TYPE(lz), lz->func, lz->it, lz->start);
|
return Py_BuildValue("O(OO)l", Py_TYPE(lz), lz->func, lz->it, lz->start);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
dropwhile_setstate(dropwhileobject *lz, PyObject *state)
|
dropwhile_setstate(dropwhileobject *lz, PyObject *state)
|
||||||
{
|
{
|
||||||
|
ITERTOOL_PICKLE_DEPRECATION;
|
||||||
int start = PyObject_IsTrue(state);
|
int start = PyObject_IsTrue(state);
|
||||||
if (start < 0)
|
if (start < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1584,12 +1604,14 @@ takewhile_next(takewhileobject *lz)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
takewhile_reduce(takewhileobject *lz, PyObject *Py_UNUSED(ignored))
|
takewhile_reduce(takewhileobject *lz, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
ITERTOOL_PICKLE_DEPRECATION;
|
||||||
return Py_BuildValue("O(OO)l", Py_TYPE(lz), lz->func, lz->it, lz->stop);
|
return Py_BuildValue("O(OO)l", Py_TYPE(lz), lz->func, lz->it, lz->stop);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
takewhile_reduce_setstate(takewhileobject *lz, PyObject *state)
|
takewhile_reduce_setstate(takewhileobject *lz, PyObject *state)
|
||||||
{
|
{
|
||||||
|
ITERTOOL_PICKLE_DEPRECATION;
|
||||||
int stop = PyObject_IsTrue(state);
|
int stop = PyObject_IsTrue(state);
|
||||||
|
|
||||||
if (stop < 0)
|
if (stop < 0)
|
||||||
|
@ -1786,6 +1808,7 @@ empty:
|
||||||
static PyObject *
|
static PyObject *
|
||||||
islice_reduce(isliceobject *lz, PyObject *Py_UNUSED(ignored))
|
islice_reduce(isliceobject *lz, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
ITERTOOL_PICKLE_DEPRECATION;
|
||||||
/* When unpickled, generate a new object with the same bounds,
|
/* When unpickled, generate a new object with the same bounds,
|
||||||
* then 'setstate' with the next and count
|
* then 'setstate' with the next and count
|
||||||
*/
|
*/
|
||||||
|
@ -1818,6 +1841,7 @@ islice_reduce(isliceobject *lz, PyObject *Py_UNUSED(ignored))
|
||||||
static PyObject *
|
static PyObject *
|
||||||
islice_setstate(isliceobject *lz, PyObject *state)
|
islice_setstate(isliceobject *lz, PyObject *state)
|
||||||
{
|
{
|
||||||
|
ITERTOOL_PICKLE_DEPRECATION;
|
||||||
Py_ssize_t cnt = PyLong_AsSsize_t(state);
|
Py_ssize_t cnt = PyLong_AsSsize_t(state);
|
||||||
|
|
||||||
if (cnt == -1 && PyErr_Occurred())
|
if (cnt == -1 && PyErr_Occurred())
|
||||||
|
@ -1953,6 +1977,7 @@ starmap_next(starmapobject *lz)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
starmap_reduce(starmapobject *lz, PyObject *Py_UNUSED(ignored))
|
starmap_reduce(starmapobject *lz, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
ITERTOOL_PICKLE_DEPRECATION;
|
||||||
/* Just pickle the iterator */
|
/* Just pickle the iterator */
|
||||||
return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->func, lz->it);
|
return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->func, lz->it);
|
||||||
}
|
}
|
||||||
|
@ -2109,6 +2134,7 @@ chain_next(chainobject *lz)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
chain_reduce(chainobject *lz, PyObject *Py_UNUSED(ignored))
|
chain_reduce(chainobject *lz, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
ITERTOOL_PICKLE_DEPRECATION;
|
||||||
if (lz->source) {
|
if (lz->source) {
|
||||||
/* we can't pickle function objects (itertools.from_iterable) so
|
/* we can't pickle function objects (itertools.from_iterable) so
|
||||||
* we must use setstate to replace the iterable. One day we
|
* we must use setstate to replace the iterable. One day we
|
||||||
|
@ -2128,6 +2154,7 @@ chain_reduce(chainobject *lz, PyObject *Py_UNUSED(ignored))
|
||||||
static PyObject *
|
static PyObject *
|
||||||
chain_setstate(chainobject *lz, PyObject *state)
|
chain_setstate(chainobject *lz, PyObject *state)
|
||||||
{
|
{
|
||||||
|
ITERTOOL_PICKLE_DEPRECATION;
|
||||||
PyObject *source, *active=NULL;
|
PyObject *source, *active=NULL;
|
||||||
|
|
||||||
if (!PyTuple_Check(state)) {
|
if (!PyTuple_Check(state)) {
|
||||||
|
@ -2403,6 +2430,7 @@ empty:
|
||||||
static PyObject *
|
static PyObject *
|
||||||
product_reduce(productobject *lz, PyObject *Py_UNUSED(ignored))
|
product_reduce(productobject *lz, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
ITERTOOL_PICKLE_DEPRECATION;
|
||||||
if (lz->stopped) {
|
if (lz->stopped) {
|
||||||
return Py_BuildValue("O(())", Py_TYPE(lz));
|
return Py_BuildValue("O(())", Py_TYPE(lz));
|
||||||
} else if (lz->result == NULL) {
|
} else if (lz->result == NULL) {
|
||||||
|
@ -2433,6 +2461,7 @@ product_reduce(productobject *lz, PyObject *Py_UNUSED(ignored))
|
||||||
static PyObject *
|
static PyObject *
|
||||||
product_setstate(productobject *lz, PyObject *state)
|
product_setstate(productobject *lz, PyObject *state)
|
||||||
{
|
{
|
||||||
|
ITERTOOL_PICKLE_DEPRECATION;
|
||||||
PyObject *result;
|
PyObject *result;
|
||||||
Py_ssize_t n, i;
|
Py_ssize_t n, i;
|
||||||
|
|
||||||
|
@ -2711,6 +2740,7 @@ empty:
|
||||||
static PyObject *
|
static PyObject *
|
||||||
combinations_reduce(combinationsobject *lz, PyObject *Py_UNUSED(ignored))
|
combinations_reduce(combinationsobject *lz, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
ITERTOOL_PICKLE_DEPRECATION;
|
||||||
if (lz->result == NULL) {
|
if (lz->result == NULL) {
|
||||||
return Py_BuildValue("O(On)", Py_TYPE(lz), lz->pool, lz->r);
|
return Py_BuildValue("O(On)", Py_TYPE(lz), lz->pool, lz->r);
|
||||||
} else if (lz->stopped) {
|
} else if (lz->stopped) {
|
||||||
|
@ -2740,6 +2770,7 @@ combinations_reduce(combinationsobject *lz, PyObject *Py_UNUSED(ignored))
|
||||||
static PyObject *
|
static PyObject *
|
||||||
combinations_setstate(combinationsobject *lz, PyObject *state)
|
combinations_setstate(combinationsobject *lz, PyObject *state)
|
||||||
{
|
{
|
||||||
|
ITERTOOL_PICKLE_DEPRECATION;
|
||||||
PyObject *result;
|
PyObject *result;
|
||||||
Py_ssize_t i;
|
Py_ssize_t i;
|
||||||
Py_ssize_t n = PyTuple_GET_SIZE(lz->pool);
|
Py_ssize_t n = PyTuple_GET_SIZE(lz->pool);
|
||||||
|
@ -3019,6 +3050,7 @@ empty:
|
||||||
static PyObject *
|
static PyObject *
|
||||||
cwr_reduce(cwrobject *lz, PyObject *Py_UNUSED(ignored))
|
cwr_reduce(cwrobject *lz, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
ITERTOOL_PICKLE_DEPRECATION;
|
||||||
if (lz->result == NULL) {
|
if (lz->result == NULL) {
|
||||||
return Py_BuildValue("O(On)", Py_TYPE(lz), lz->pool, lz->r);
|
return Py_BuildValue("O(On)", Py_TYPE(lz), lz->pool, lz->r);
|
||||||
} else if (lz->stopped) {
|
} else if (lz->stopped) {
|
||||||
|
@ -3047,6 +3079,7 @@ cwr_reduce(cwrobject *lz, PyObject *Py_UNUSED(ignored))
|
||||||
static PyObject *
|
static PyObject *
|
||||||
cwr_setstate(cwrobject *lz, PyObject *state)
|
cwr_setstate(cwrobject *lz, PyObject *state)
|
||||||
{
|
{
|
||||||
|
ITERTOOL_PICKLE_DEPRECATION;
|
||||||
PyObject *result;
|
PyObject *result;
|
||||||
Py_ssize_t n, i;
|
Py_ssize_t n, i;
|
||||||
|
|
||||||
|
@ -3354,6 +3387,7 @@ empty:
|
||||||
static PyObject *
|
static PyObject *
|
||||||
permutations_reduce(permutationsobject *po, PyObject *Py_UNUSED(ignored))
|
permutations_reduce(permutationsobject *po, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
ITERTOOL_PICKLE_DEPRECATION;
|
||||||
if (po->result == NULL) {
|
if (po->result == NULL) {
|
||||||
return Py_BuildValue("O(On)", Py_TYPE(po), po->pool, po->r);
|
return Py_BuildValue("O(On)", Py_TYPE(po), po->pool, po->r);
|
||||||
} else if (po->stopped) {
|
} else if (po->stopped) {
|
||||||
|
@ -3396,6 +3430,7 @@ permutations_reduce(permutationsobject *po, PyObject *Py_UNUSED(ignored))
|
||||||
static PyObject *
|
static PyObject *
|
||||||
permutations_setstate(permutationsobject *po, PyObject *state)
|
permutations_setstate(permutationsobject *po, PyObject *state)
|
||||||
{
|
{
|
||||||
|
ITERTOOL_PICKLE_DEPRECATION;
|
||||||
PyObject *indices, *cycles, *result;
|
PyObject *indices, *cycles, *result;
|
||||||
Py_ssize_t n, i;
|
Py_ssize_t n, i;
|
||||||
|
|
||||||
|
@ -3593,6 +3628,7 @@ accumulate_next(accumulateobject *lz)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
accumulate_reduce(accumulateobject *lz, PyObject *Py_UNUSED(ignored))
|
accumulate_reduce(accumulateobject *lz, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
ITERTOOL_PICKLE_DEPRECATION;
|
||||||
itertools_state *state = lz->state;
|
itertools_state *state = lz->state;
|
||||||
|
|
||||||
if (lz->initial != Py_None) {
|
if (lz->initial != Py_None) {
|
||||||
|
@ -3628,6 +3664,7 @@ accumulate_reduce(accumulateobject *lz, PyObject *Py_UNUSED(ignored))
|
||||||
static PyObject *
|
static PyObject *
|
||||||
accumulate_setstate(accumulateobject *lz, PyObject *state)
|
accumulate_setstate(accumulateobject *lz, PyObject *state)
|
||||||
{
|
{
|
||||||
|
ITERTOOL_PICKLE_DEPRECATION;
|
||||||
Py_INCREF(state);
|
Py_INCREF(state);
|
||||||
Py_XSETREF(lz->total, state);
|
Py_XSETREF(lz->total, state);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
|
@ -3776,6 +3813,7 @@ compress_next(compressobject *lz)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
compress_reduce(compressobject *lz, PyObject *Py_UNUSED(ignored))
|
compress_reduce(compressobject *lz, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
ITERTOOL_PICKLE_DEPRECATION;
|
||||||
return Py_BuildValue("O(OO)", Py_TYPE(lz),
|
return Py_BuildValue("O(OO)", Py_TYPE(lz),
|
||||||
lz->data, lz->selectors);
|
lz->data, lz->selectors);
|
||||||
}
|
}
|
||||||
|
@ -3908,6 +3946,7 @@ filterfalse_next(filterfalseobject *lz)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
filterfalse_reduce(filterfalseobject *lz, PyObject *Py_UNUSED(ignored))
|
filterfalse_reduce(filterfalseobject *lz, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
ITERTOOL_PICKLE_DEPRECATION;
|
||||||
return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->func, lz->it);
|
return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->func, lz->it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4135,6 +4174,7 @@ count_repr(countobject *lz)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
count_reduce(countobject *lz, PyObject *Py_UNUSED(ignored))
|
count_reduce(countobject *lz, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
ITERTOOL_PICKLE_DEPRECATION;
|
||||||
if (lz->cnt == PY_SSIZE_T_MAX)
|
if (lz->cnt == PY_SSIZE_T_MAX)
|
||||||
return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->long_cnt, lz->long_step);
|
return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->long_cnt, lz->long_step);
|
||||||
return Py_BuildValue("O(n)", Py_TYPE(lz), lz->cnt);
|
return Py_BuildValue("O(n)", Py_TYPE(lz), lz->cnt);
|
||||||
|
@ -4258,6 +4298,7 @@ PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(
|
||||||
static PyObject *
|
static PyObject *
|
||||||
repeat_reduce(repeatobject *ro, PyObject *Py_UNUSED(ignored))
|
repeat_reduce(repeatobject *ro, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
ITERTOOL_PICKLE_DEPRECATION;
|
||||||
/* unpickle this so that a new repeat iterator is constructed with an
|
/* unpickle this so that a new repeat iterator is constructed with an
|
||||||
* object, then call __setstate__ on it to set cnt
|
* object, then call __setstate__ on it to set cnt
|
||||||
*/
|
*/
|
||||||
|
@ -4478,7 +4519,7 @@ zip_longest_next(ziplongestobject *lz)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
zip_longest_reduce(ziplongestobject *lz, PyObject *Py_UNUSED(ignored))
|
zip_longest_reduce(ziplongestobject *lz, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
ITERTOOL_PICKLE_DEPRECATION;
|
||||||
/* Create a new tuple with empty sequences where appropriate to pickle.
|
/* Create a new tuple with empty sequences where appropriate to pickle.
|
||||||
* Then use setstate to set the fillvalue
|
* Then use setstate to set the fillvalue
|
||||||
*/
|
*/
|
||||||
|
@ -4505,6 +4546,7 @@ zip_longest_reduce(ziplongestobject *lz, PyObject *Py_UNUSED(ignored))
|
||||||
static PyObject *
|
static PyObject *
|
||||||
zip_longest_setstate(ziplongestobject *lz, PyObject *state)
|
zip_longest_setstate(ziplongestobject *lz, PyObject *state)
|
||||||
{
|
{
|
||||||
|
ITERTOOL_PICKLE_DEPRECATION;
|
||||||
Py_INCREF(state);
|
Py_INCREF(state);
|
||||||
Py_XSETREF(lz->fillvalue, state);
|
Py_XSETREF(lz->fillvalue, state);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue