@@ -874,26 +874,6 @@ def side_effect(self):
874874 self .assertDictEqual (dict1 , dict .fromkeys ((0 , 4.2 )))
875875 self .assertDictEqual (dict2 , dict .fromkeys ((0 , Key (), 4.2 )))
876876
877- def test_getitem_re_entrant_clear_during_copy (self ):
878- class Evil (self .OrderedDict ):
879- def __getitem__ (self , key ):
880- super ().clear ()
881- return None
882-
883- evil_dict = Evil ([(i , i ) for i in range (4 )])
884- with self .assertRaises (RuntimeError ):
885- result = evil_dict .copy ()
886-
887- def test_getitem_re_entrant_modify_during_copy (self ):
888- class Modifier (self .OrderedDict ):
889- def __getitem__ (self , key ):
890- self ['new_key' ] = 'new_value'
891- return super ().__getitem__ (key )
892-
893- original = Modifier ([(1 , 'one' ), (2 , 'two' )])
894- with self .assertRaises (RuntimeError ):
895- result = original .copy ()
896-
897877
898878@unittest .skipUnless (c_coll , 'requires the C version of the collections module' )
899879class CPythonOrderedDictTests (OrderedDictTests ,
@@ -991,6 +971,77 @@ def test_weakref_list_is_not_traversed(self):
991971
992972 gc .collect ()
993973
974+ def test_getitem_re_entrant_clear_during_copy (self ):
975+ class Evil (self .OrderedDict ):
976+ def __getitem__ (self , key ):
977+ super ().clear ()
978+ return None
979+
980+ evil_dict = Evil ([(i , i ) for i in range (4 )])
981+ with self .assertRaises (RuntimeError ):
982+ result = evil_dict .copy ()
983+
984+ def test_getitem_re_entrant_modify_during_copy (self ):
985+ class Modifier (self .OrderedDict ):
986+ def __getitem__ (self , key ):
987+ self ['new_key' ] = 'new_value'
988+ return super ().__getitem__ (key )
989+
990+ original = Modifier ([(1 , 'one' ), (2 , 'two' )])
991+ with self .assertRaises (RuntimeError ):
992+ result = original .copy ()
993+
994+ def test_getitem_re_entrant_delete_during_copy (self ):
995+ class Deleter (self .OrderedDict ):
996+ call_count = 0
997+ def __getitem__ (self , key ):
998+ Deleter .call_count += 1
999+ if Deleter .call_count == 1 :
1000+ del self [3 ]
1001+ return super ().__getitem__ (key )
1002+
1003+ original = Deleter ([(1 , 'one' ), (2 , 'two' ), (3 , 'three' )])
1004+ with self .assertRaises (RuntimeError ):
1005+ result = original .copy ()
1006+
1007+ def test_getitem_re_entrant_add_during_copy (self ):
1008+ class MultiAdder (self .OrderedDict ):
1009+ def __getitem__ (self , key ):
1010+ self ['new_key1' ] = 'new_value1'
1011+ return super ().__getitem__ (key )
1012+
1013+ original = MultiAdder ([(1 , 'one' ), (2 , 'two' ), (3 , 'three' )])
1014+ with self .assertRaises (RuntimeError ):
1015+ result = original .copy ()
1016+
1017+ def test_getitem_re_entrant_pop_during_copy (self ):
1018+ class Popper (self .OrderedDict ):
1019+ call_count = 0
1020+ def __getitem__ (self , key ):
1021+ Popper .call_count += 1
1022+ if Popper .call_count == 1 :
1023+ self .pop (3 , None )
1024+ return super ().__getitem__ (key )
1025+
1026+ original = Popper ([(1 , 'one' ), (2 , 'two' ), (3 , 'three' )])
1027+ with self .assertRaises (RuntimeError ):
1028+ result = original .copy ()
1029+
1030+ def test_getitem_re_entrant_mixed_mutation_during_copy (self ):
1031+ class MixedMutator (self .OrderedDict ):
1032+ call_count = 0
1033+ def __getitem__ (self , key ):
1034+ MixedMutator .call_count += 1
1035+ if MixedMutator .call_count == 1 :
1036+ del self [3 ]
1037+ elif MixedMutator .call_count == 2 :
1038+ self ['new_key' ] = 'new_value'
1039+ return super ().__getitem__ (key )
1040+
1041+ original = MixedMutator ([(1 , 'one' ), (2 , 'two' ), (3 , 'three' ), (4 , 'four' )])
1042+ with self .assertRaises (RuntimeError ):
1043+ result = original .copy ()
1044+
9941045
9951046class PurePythonOrderedDictSubclassTests (PurePythonOrderedDictTests ):
9961047
0 commit comments