@@ -4554,36 +4554,103 @@ def __reduce__(self):
45544554 expected = "changed size during iteration"
45554555 self .assertIn (expected , str (e ))
45564556
4557- def test_fast_save_enter_leave (self ):
4558- # gh-146059: Check that fast_save_leave () is called when
4557+ def fast_save_enter (self , create_data , minprotocol = 0 ):
4558+ # gh-146059: Check that fast_save () is called when
45594559 # fast_save_enter() is called.
45604560 if not hasattr (self , "pickler" ):
45614561 self .skipTest ("need Pickler class" )
45624562
4563- limit = FAST_NESTING_LIMIT * 2
4563+ data = [create_data (i ) for i in range (FAST_NESTING_LIMIT * 2 )]
4564+ data = {"key" : data }
4565+ protocols = range (minprotocol , pickle .HIGHEST_PROTOCOL + 1 )
45644566 for proto in protocols :
4565- for tested_type in (frozenset , list , dict ):
4566- with self .subTest (proto = proto , tested_type = tested_type ):
4567- buf = io .BytesIO ()
4568- pickler = self .pickler (buf , protocol = proto )
4569- # Enable fast mode (disables memo, enables cycle detection)
4570- pickler .fast = 1
4571-
4572- if tested_type == frozenset :
4573- data = [frozenset ([i ]) for i in range (limit )]
4574- elif tested_type == list :
4575- data = [[i ] for i in range (limit )]
4576- elif tested_type == dict :
4577- data = [{"key" : 123 } for i in range (limit )]
4578- else :
4579- self .fail ("unknown tested_type" )
4580- data = {"key" : data }
4581- pickler .dump (data )
4567+ with self .subTest (proto = proto ):
4568+ buf = io .BytesIO ()
4569+ pickler = self .pickler (buf , protocol = proto )
4570+ # Enable fast mode (disables memo, enables cycle detection)
4571+ pickler .fast = 1
4572+ pickler .dump (data )
4573+
4574+ buf .seek (0 )
4575+ data2 = self .unpickler (buf ).load ()
4576+ self .assertEqual (data2 , data )
4577+
4578+ def test_fast_save_enter_tuple (self ):
4579+ self .fast_save_enter (lambda i : (i ,))
4580+
4581+ def test_fast_save_enter_list (self ):
4582+ self .fast_save_enter (lambda i : [i ])
4583+
4584+ def test_fast_save_enter_frozenset (self ):
4585+ self .fast_save_enter (lambda i : frozenset ([i ]))
45824586
4583- buf .seek (0 )
4584- data2 = self .unpickler (buf ).load ()
4587+ def test_fast_save_enter_set (self ):
4588+ self .fast_save_enter (lambda i : set ([i ]))
4589+
4590+ def test_fast_save_enter_frozendict (self ):
4591+ if self .py_version < (3 , 15 ):
4592+ self .skipTest ('need frozendict' )
4593+ self .fast_save_enter (lambda i : frozendict (key = i ), minprotocol = 2 )
4594+
4595+ def test_fast_save_enter_dict (self ):
4596+ self .fast_save_enter (lambda i : {"key" : i })
4597+
4598+ def deep_nested_struct (self , seed , create_nested ,
4599+ minprotocol = 0 , compare_equal = True ,
4600+ depth = FAST_NESTING_LIMIT * 2 ):
4601+ # gh-146059: Check that fast_save() is called when
4602+ # fast_save_enter() is called.
4603+ if not hasattr (self , "pickler" ):
4604+ self .skipTest ("need Pickler class" )
4605+
4606+ data = seed
4607+ for i in range (depth ):
4608+ data = create_nested (data )
4609+ data = {"key" : data }
4610+ protocols = range (minprotocol , pickle .HIGHEST_PROTOCOL + 1 )
4611+ for proto in protocols :
4612+ with self .subTest (proto = proto ):
4613+ buf = io .BytesIO ()
4614+ pickler = self .pickler (buf , protocol = proto )
4615+ # Enable fast mode (disables memo, enables cycle detection)
4616+ pickler .fast = 1
4617+ pickler .dump (data )
4618+
4619+ buf .seek (0 )
4620+ data2 = self .unpickler (buf ).load ()
4621+ if compare_equal :
45854622 self .assertEqual (data2 , data )
45864623
4624+ def test_deep_nested_struct_tuple (self ):
4625+ self .deep_nested_struct ((1 ,), lambda data : (data ,))
4626+
4627+ def test_deep_nested_struct_list (self ):
4628+ self .deep_nested_struct ([1 ], lambda data : [data ])
4629+
4630+ def test_deep_nested_struct_frozenset (self ):
4631+ self .deep_nested_struct (frozenset ((1 ,)),
4632+ lambda data : frozenset ((1 , data )))
4633+
4634+ def test_deep_nested_struct_set (self ):
4635+ def create_nested (data ):
4636+ obj = Object ()
4637+ obj .value = data
4638+ return {obj }
4639+
4640+ self .deep_nested_struct ({1 }, create_nested ,
4641+ depth = FAST_NESTING_LIMIT + 1 ,
4642+ compare_equal = False )
4643+
4644+ def test_deep_nested_struct_frozendict (self ):
4645+ if self .py_version < (3 , 15 ):
4646+ self .skipTest ('need frozendict' )
4647+ self .deep_nested_struct (frozendict (x = 1 ),
4648+ lambda data : frozendict (x = data ),
4649+ minprotocol = 2 )
4650+
4651+ def test_deep_nested_struct_dict (self ):
4652+ self .deep_nested_struct ({'x' : 1 }, lambda data : {'x' : data })
4653+
45874654
45884655class BigmemPickleTests :
45894656
0 commit comments