88import unittest
99import weakref
1010from test import support
11+ from test .support import import_helper
1112
1213
1314class DictTest (unittest .TestCase ):
@@ -896,6 +897,14 @@ def _tracked(self, t):
896897 gc .collect ()
897898 self .assertTrue (gc .is_tracked (t ), t )
898899
900+ def test_string_keys_can_track_values (self ):
901+ # Test that this doesn't leak.
902+ for i in range (10 ):
903+ d = {}
904+ for j in range (10 ):
905+ d [str (j )] = j
906+ d ["foo" ] = d
907+
899908 @support .cpython_only
900909 def test_track_literals (self ):
901910 # Test GC-optimization of dict literals
@@ -999,8 +1008,8 @@ class C:
9991008
10001009 @support .cpython_only
10011010 def test_splittable_setdefault (self ):
1002- """split table must be combined when setdefault()
1003- breaks insertion order """
1011+ """split table must keep correct insertion
1012+ order when attributes are adding using setdefault() """
10041013 a , b = self .make_shared_key_dict (2 )
10051014
10061015 a ['a' ] = 1
@@ -1010,7 +1019,6 @@ def test_splittable_setdefault(self):
10101019 size_b = sys .getsizeof (b )
10111020 b ['a' ] = 1
10121021
1013- self .assertGreater (size_b , size_a )
10141022 self .assertEqual (list (a ), ['x' , 'y' , 'z' , 'a' , 'b' ])
10151023 self .assertEqual (list (b ), ['x' , 'y' , 'z' , 'b' , 'a' ])
10161024
@@ -1025,7 +1033,6 @@ def test_splittable_del(self):
10251033 with self .assertRaises (KeyError ):
10261034 del a ['y' ]
10271035
1028- self .assertGreater (sys .getsizeof (a ), orig_size )
10291036 self .assertEqual (list (a ), ['x' , 'z' ])
10301037 self .assertEqual (list (b ), ['x' , 'y' , 'z' ])
10311038
@@ -1036,16 +1043,12 @@ def test_splittable_del(self):
10361043
10371044 @support .cpython_only
10381045 def test_splittable_pop (self ):
1039- """split table must be combined when d.pop(k)"""
10401046 a , b = self .make_shared_key_dict (2 )
10411047
1042- orig_size = sys .getsizeof (a )
1043-
1044- a .pop ('y' ) # split table is combined
1048+ a .pop ('y' )
10451049 with self .assertRaises (KeyError ):
10461050 a .pop ('y' )
10471051
1048- self .assertGreater (sys .getsizeof (a ), orig_size )
10491052 self .assertEqual (list (a ), ['x' , 'z' ])
10501053 self .assertEqual (list (b ), ['x' , 'y' , 'z' ])
10511054
@@ -1080,34 +1083,21 @@ def test_splittable_popitem(self):
10801083 self .assertEqual (list (b ), ['x' , 'y' , 'z' ])
10811084
10821085 @support .cpython_only
1083- def test_splittable_setattr_after_pop (self ):
1084- """setattr() must not convert combined table into split table."""
1085- # Issue 28147
1086- import _testcapi
1087-
1086+ def test_splittable_update (self ):
1087+ """dict.update(other) must preserve order in other."""
10881088 class C :
1089- pass
1090- a = C ()
1091-
1092- a .a = 1
1093- self .assertTrue (_testcapi .dict_hassplittable (a .__dict__ ))
1094-
1095- # dict.pop() convert it to combined table
1096- a .__dict__ .pop ('a' )
1097- self .assertFalse (_testcapi .dict_hassplittable (a .__dict__ ))
1098-
1099- # But C should not convert a.__dict__ to split table again.
1100- a .a = 1
1101- self .assertFalse (_testcapi .dict_hassplittable (a .__dict__ ))
1089+ def __init__ (self , order ):
1090+ if order :
1091+ self .a , self .b , self .c = 1 , 2 , 3
1092+ else :
1093+ self .c , self .b , self .a = 1 , 2 , 3
1094+ o = C (True )
1095+ o = C (False ) # o.__dict__ has reversed order.
1096+ self .assertEqual (list (o .__dict__ ), ["c" , "b" , "a" ])
11021097
1103- # Same for popitem()
1104- a = C ()
1105- a .a = 2
1106- self .assertTrue (_testcapi .dict_hassplittable (a .__dict__ ))
1107- a .__dict__ .popitem ()
1108- self .assertFalse (_testcapi .dict_hassplittable (a .__dict__ ))
1109- a .a = 3
1110- self .assertFalse (_testcapi .dict_hassplittable (a .__dict__ ))
1098+ d = {}
1099+ d .update (o .__dict__ )
1100+ self .assertEqual (list (d ), ["c" , "b" , "a" ])
11111101
11121102 def test_iterator_pickling (self ):
11131103 for proto in range (pickle .HIGHEST_PROTOCOL + 1 ):
@@ -1586,7 +1576,8 @@ class CAPITest(unittest.TestCase):
15861576 # Test _PyDict_GetItem_KnownHash()
15871577 @support .cpython_only
15881578 def test_getitem_knownhash (self ):
1589- from _testcapi import dict_getitem_knownhash
1579+ _testcapi = import_helper .import_module ('_testcapi' )
1580+ dict_getitem_knownhash = _testcapi .dict_getitem_knownhash
15901581
15911582 d = {'x' : 1 , 'y' : 2 , 'z' : 3 }
15921583 self .assertEqual (dict_getitem_knownhash (d , 'x' , hash ('x' )), 1 )
0 commit comments