Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit402ee5a

Browse files
authored
pythonGH-101588: Deprecate pickle/copy/deepcopy support in itertools (pythonGH-104965)
1 parent328422c commit402ee5a

File tree

4 files changed

+97
-3
lines changed

4 files changed

+97
-3
lines changed

‎Doc/whatsnew/3.12.rst‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1069,6 +1069,12 @@ Pending Removal in Python 3.14
10691069
functions that have been deprecated since Python 2 but only gained a
10701070
proper:exc:`DeprecationWarning` in 3.12. Remove them in 3.14.
10711071

1072+
*:mod:`itertools` had undocumented, inefficient, historically buggy,
1073+
and inconsistent support for copy, deepcopy, and pickle operations.
1074+
This will be removed in 3.14 for a significant reduction in code
1075+
volume and maintenance burden.
1076+
(Contributed by Raymond Hettinger in:gh:`101588`.)
1077+
10721078
* Accessing ``co_lnotab`` was deprecated in:pep:`626` since 3.10
10731079
and was planned to be removed in 3.12
10741080
but it only got a proper:exc:`DeprecationWarning` in 3.12.

‎Lib/test/test_itertools.py‎

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,26 @@
1515
importstruct
1616
importthreading
1717
importgc
18+
importwarnings
19+
20+
defpickle_deprecated(testfunc):
21+
""" Run the test three times.
22+
First, verify that a Deprecation Warning is raised.
23+
Second, run normally but with DeprecationWarnings temporarily disabled.
24+
Third, run with warnings promoted to errors.
25+
"""
26+
definner(self):
27+
withself.assertWarns(DeprecationWarning):
28+
testfunc(self)
29+
withwarnings.catch_warnings():
30+
warnings.simplefilter("ignore",category=DeprecationWarning)
31+
testfunc(self)
32+
withwarnings.catch_warnings():
33+
warnings.simplefilter("error",category=DeprecationWarning)
34+
withself.assertRaises((DeprecationWarning,AssertionError,SystemError)):
35+
testfunc(self)
36+
37+
returninner
1838

1939
maxsize=support.MAX_Py_ssize_t
2040
minsize=-maxsize-1
@@ -124,6 +144,7 @@ def expand(it, i=0):
124144
c=expand(compare[took:])
125145
self.assertEqual(a,c);
126146

147+
@pickle_deprecated
127148
deftest_accumulate(self):
128149
self.assertEqual(list(accumulate(range(10))),# one positional arg
129150
[0,1,3,6,10,15,21,28,36,45])
@@ -220,6 +241,7 @@ def test_chain_from_iterable(self):
220241
self.assertRaises(TypeError,list,chain.from_iterable([2,3]))
221242
self.assertEqual(list(islice(chain.from_iterable(repeat(range(5))),2)), [0,1])
222243

244+
@pickle_deprecated
223245
deftest_chain_reducible(self):
224246
foroperin [copy.deepcopy]+picklecopiers:
225247
it=chain('abc','def')
@@ -233,6 +255,7 @@ def test_chain_reducible(self):
233255
forprotoinrange(pickle.HIGHEST_PROTOCOL+1):
234256
self.pickletest(proto,chain('abc','def'),compare=list('abcdef'))
235257

258+
@pickle_deprecated
236259
deftest_chain_setstate(self):
237260
self.assertRaises(TypeError,chain().__setstate__, ())
238261
self.assertRaises(TypeError,chain().__setstate__, [])
@@ -246,6 +269,7 @@ def test_chain_setstate(self):
246269
it.__setstate__((iter(['abc','def']),iter(['ghi'])))
247270
self.assertEqual(list(it), ['ghi','a','b','c','d','e','f'])
248271

272+
@pickle_deprecated
249273
deftest_combinations(self):
250274
self.assertRaises(TypeError,combinations,'abc')# missing r argument
251275
self.assertRaises(TypeError,combinations,'abc',2,1)# too many arguments
@@ -269,7 +293,6 @@ def test_combinations(self):
269293
self.assertEqual(list(op(testIntermediate)),
270294
[(0,1,3), (0,2,3), (1,2,3)])
271295

272-
273296
defcombinations1(iterable,r):
274297
'Pure python version shown in the docs'
275298
pool=tuple(iterable)
@@ -337,6 +360,7 @@ def test_combinations_tuple_reuse(self):
337360
self.assertEqual(len(set(map(id,combinations('abcde',3)))),1)
338361
self.assertNotEqual(len(set(map(id,list(combinations('abcde',3))))),1)
339362

363+
@pickle_deprecated
340364
deftest_combinations_with_replacement(self):
341365
cwr=combinations_with_replacement
342366
self.assertRaises(TypeError,cwr,'abc')# missing r argument
@@ -425,6 +449,7 @@ def test_combinations_with_replacement_tuple_reuse(self):
425449
self.assertEqual(len(set(map(id,cwr('abcde',3)))),1)
426450
self.assertNotEqual(len(set(map(id,list(cwr('abcde',3))))),1)
427451

452+
@pickle_deprecated
428453
deftest_permutations(self):
429454
self.assertRaises(TypeError,permutations)# too few arguments
430455
self.assertRaises(TypeError,permutations,'abc',2,1)# too many arguments
@@ -531,6 +556,7 @@ def test_combinatorics(self):
531556
self.assertEqual(comb,list(filter(set(perm).__contains__,cwr)))# comb: cwr that is a perm
532557
self.assertEqual(comb,sorted(set(cwr)&set(perm)))# comb: both a cwr and a perm
533558

559+
@pickle_deprecated
534560
deftest_compress(self):
535561
self.assertEqual(list(compress(data='ABCDEF',selectors=[1,0,1,0,1,1])),list('ACEF'))
536562
self.assertEqual(list(compress('ABCDEF', [1,0,1,0,1,1])),list('ACEF'))
@@ -564,7 +590,7 @@ def test_compress(self):
564590
next(testIntermediate)
565591
self.assertEqual(list(op(testIntermediate)),list(result2))
566592

567-
593+
@pickle_deprecated
568594
deftest_count(self):
569595
self.assertEqual(lzip('abc',count()), [('a',0), ('b',1), ('c',2)])
570596
self.assertEqual(lzip('abc',count(3)), [('a',3), ('b',4), ('c',5)])
@@ -613,6 +639,7 @@ def test_count(self):
613639
#check proper internal error handling for large "step' sizes
614640
count(1,maxsize+5);sys.exc_info()
615641

642+
@pickle_deprecated
616643
deftest_count_with_stride(self):
617644
self.assertEqual(lzip('abc',count(2,3)), [('a',2), ('b',5), ('c',8)])
618645
self.assertEqual(lzip('abc',count(start=2,step=3)),
@@ -675,6 +702,7 @@ def test_cycle(self):
675702
self.assertRaises(TypeError,cycle,5)
676703
self.assertEqual(list(islice(cycle(gen3()),10)), [0,1,2,0,1,2,0,1,2,0])
677704

705+
@pickle_deprecated
678706
deftest_cycle_copy_pickle(self):
679707
# check copy, deepcopy, pickle
680708
c=cycle('abc')
@@ -711,6 +739,7 @@ def test_cycle_copy_pickle(self):
711739
d=pickle.loads(p)# rebuild the cycle object
712740
self.assertEqual(take(20,d),list('cdeabcdeabcdeabcdeab'))
713741

742+
@pickle_deprecated
714743
deftest_cycle_unpickle_compat(self):
715744
testcases= [
716745
b'citertools\ncycle\n(c__builtin__\niter\n((lI1\naI2\naI3\natRI1\nbtR((lI1\naI0\ntb.',
@@ -742,6 +771,7 @@ def test_cycle_unpickle_compat(self):
742771
it=pickle.loads(t)
743772
self.assertEqual(take(10,it), [2,3,1,2,3,1,2,3,1,2])
744773

774+
@pickle_deprecated
745775
deftest_cycle_setstate(self):
746776
# Verify both modes for restoring state
747777

@@ -778,6 +808,7 @@ def test_cycle_setstate(self):
778808
self.assertRaises(TypeError,cycle('').__setstate__, ())
779809
self.assertRaises(TypeError,cycle('').__setstate__, ([],))
780810

811+
@pickle_deprecated
781812
deftest_groupby(self):
782813
# Check whether it accepts arguments correctly
783814
self.assertEqual([],list(groupby([])))
@@ -935,6 +966,7 @@ def test_filter(self):
935966
c=filter(isEven,range(6))
936967
self.pickletest(proto,c)
937968

969+
@pickle_deprecated
938970
deftest_filterfalse(self):
939971
self.assertEqual(list(filterfalse(isEven,range(6))), [1,3,5])
940972
self.assertEqual(list(filterfalse(None, [0,1,0,2,0])), [0,0,0])
@@ -965,6 +997,7 @@ def test_zip(self):
965997
lzip('abc','def'))
966998

967999
@support.impl_detail("tuple reuse is specific to CPython")
1000+
@pickle_deprecated
9681001
deftest_zip_tuple_reuse(self):
9691002
ids=list(map(id,zip('abc','def')))
9701003
self.assertEqual(min(ids),max(ids))
@@ -1040,6 +1073,7 @@ def test_zip_longest_tuple_reuse(self):
10401073
ids=list(map(id,list(zip_longest('abc','def'))))
10411074
self.assertEqual(len(dict.fromkeys(ids)),len(ids))
10421075

1076+
@pickle_deprecated
10431077
deftest_zip_longest_pickling(self):
10441078
forprotoinrange(pickle.HIGHEST_PROTOCOL+1):
10451079
self.pickletest(proto,zip_longest("abc","def"))
@@ -1186,6 +1220,7 @@ def test_product_tuple_reuse(self):
11861220
self.assertEqual(len(set(map(id,product('abc','def')))),1)
11871221
self.assertNotEqual(len(set(map(id,list(product('abc','def'))))),1)
11881222

1223+
@pickle_deprecated
11891224
deftest_product_pickling(self):
11901225
# check copy, deepcopy, pickle
11911226
forargs,resultin [
@@ -1201,6 +1236,7 @@ def test_product_pickling(self):
12011236
forprotoinrange(pickle.HIGHEST_PROTOCOL+1):
12021237
self.pickletest(proto,product(*args))
12031238

1239+
@pickle_deprecated
12041240
deftest_product_issue_25021(self):
12051241
# test that indices are properly clamped to the length of the tuples
12061242
p=product((1,2),(3,))
@@ -1211,6 +1247,7 @@ def test_product_issue_25021(self):
12111247
p.__setstate__((0,0,0x1000))# will access tuple element 1 if not clamped
12121248
self.assertRaises(StopIteration,next,p)
12131249

1250+
@pickle_deprecated
12141251
deftest_repeat(self):
12151252
self.assertEqual(list(repeat(object='a',times=3)), ['a','a','a'])
12161253
self.assertEqual(lzip(range(3),repeat('a')),
@@ -1243,6 +1280,7 @@ def test_repeat_with_negative_times(self):
12431280
self.assertEqual(repr(repeat('a',times=-1)),"repeat('a', 0)")
12441281
self.assertEqual(repr(repeat('a',times=-2)),"repeat('a', 0)")
12451282

1283+
@pickle_deprecated
12461284
deftest_map(self):
12471285
self.assertEqual(list(map(operator.pow,range(3),range(1,7))),
12481286
[0**1,1**2,2**3])
@@ -1273,6 +1311,7 @@ def test_map(self):
12731311
c=map(tupleize,'abc',count())
12741312
self.pickletest(proto,c)
12751313

1314+
@pickle_deprecated
12761315
deftest_starmap(self):
12771316
self.assertEqual(list(starmap(operator.pow,zip(range(3),range(1,7)))),
12781317
[0**1,1**2,2**3])
@@ -1300,6 +1339,7 @@ def test_starmap(self):
13001339
c=starmap(operator.pow,zip(range(3),range(1,7)))
13011340
self.pickletest(proto,c)
13021341

1342+
@pickle_deprecated
13031343
deftest_islice(self):
13041344
forargsin [# islice(args) should agree with range(args)
13051345
(10,20,3),
@@ -1394,6 +1434,7 @@ def __index__(self):
13941434
self.assertEqual(list(islice(range(100),IntLike(10),IntLike(50),IntLike(5))),
13951435
list(range(10,50,5)))
13961436

1437+
@pickle_deprecated
13971438
deftest_takewhile(self):
13981439
data= [1,3,5,20,2,4,6,8]
13991440
self.assertEqual(list(takewhile(underten,data)), [1,3,5])
@@ -1414,6 +1455,7 @@ def test_takewhile(self):
14141455
forprotoinrange(pickle.HIGHEST_PROTOCOL+1):
14151456
self.pickletest(proto,takewhile(underten,data))
14161457

1458+
@pickle_deprecated
14171459
deftest_dropwhile(self):
14181460
data= [1,3,5,20,2,4,6,8]
14191461
self.assertEqual(list(dropwhile(underten,data)), [20,2,4,6,8])
@@ -1431,6 +1473,7 @@ def test_dropwhile(self):
14311473
forprotoinrange(pickle.HIGHEST_PROTOCOL+1):
14321474
self.pickletest(proto,dropwhile(underten,data))
14331475

1476+
@pickle_deprecated
14341477
deftest_tee(self):
14351478
n=200
14361479

@@ -1732,6 +1775,7 @@ class TestExamples(unittest.TestCase):
17321775
deftest_accumulate(self):
17331776
self.assertEqual(list(accumulate([1,2,3,4,5])), [1,3,6,10,15])
17341777

1778+
@pickle_deprecated
17351779
deftest_accumulate_reducible(self):
17361780
# check copy, deepcopy, pickle
17371781
data= [1,2,3,4,5]
@@ -1747,6 +1791,7 @@ def test_accumulate_reducible(self):
17471791
self.assertEqual(list(copy.deepcopy(it)),accumulated[1:])
17481792
self.assertEqual(list(copy.copy(it)),accumulated[1:])
17491793

1794+
@pickle_deprecated
17501795
deftest_accumulate_reducible_none(self):
17511796
# Issue #25718: total is None
17521797
it=accumulate([None,None,None],operator.is_)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Deprecate undocumented copy/deepcopy/pickle support for itertools.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp