github.com/google/skylark@v0.0.0-20181101142754-a5f7082aabed/testdata/dict.sky (about) 1 # Tests of Skylark 'dict' 2 3 load("assert.sky", "assert", "freeze") 4 5 # literals 6 assert.eq({}, {}) 7 assert.eq({"a": 1}, {"a": 1}) 8 assert.eq({"a": 1,}, {"a": 1}) 9 10 # truth 11 assert.true({False: False}) 12 assert.true(not {}) 13 14 # dict + dict (undocumented and deprecated; see b/36360157). 15 assert.eq({"a": 1, "b": 2} + {"a": 3, "c": 4}, {"a": 3, "b": 2, "c": 4}) 16 17 # dict comprehension 18 assert.eq({x: x*x for x in range(3)}, {0: 0, 1: 1, 2: 4}) 19 20 # dict.pop 21 x6 = {"a": 1, "b": 2} 22 assert.eq(x6.pop("a"), 1) 23 assert.eq(str(x6), '{"b": 2}') 24 assert.fails(lambda: x6.pop("c"), "pop: missing key") 25 assert.eq(x6.pop("c", 3), 3) 26 assert.eq(x6.pop("c", None), None) # default=None tests an edge case of UnpackArgs 27 assert.eq(x6.pop("b"), 2) 28 assert.eq(len(x6), 0) 29 30 # dict.popitem 31 x7 = {"a": 1, "b": 2} 32 assert.eq([x7.popitem(), x7.popitem()], [("a", 1), ("b", 2)]) 33 assert.fails(x7.popitem, "empty dict") 34 assert.eq(len(x7), 0) 35 36 # dict.keys, dict.values 37 x8 = {"a": 1, "b": 2} 38 assert.eq(x8.keys(), ["a", "b"]) 39 assert.eq(x8.values(), [1, 2]) 40 41 # equality 42 assert.eq({"a": 1, "b": 2}, {"a": 1, "b": 2}) 43 assert.eq({"a": 1, "b": 2,}, {"a": 1, "b": 2}) 44 assert.eq({"a": 1, "b": 2}, {"b": 2, "a": 1}) 45 46 # insertion order is preserved 47 assert.eq(dict([("a", 0), ("b", 1), ("c", 2), ("b", 3)]).keys(), ["a", "b", "c"]) 48 assert.eq(dict([("b", 0), ("a", 1), ("b", 2), ("c", 3)]).keys(), ["b", "a", "c"]) 49 assert.eq(dict([("b", 0), ("a", 1), ("b", 2), ("c", 3)])["b"], 2) 50 # ...even after rehashing (which currently occurs after key 'i'): 51 small = dict([("a", 0), ("b", 1), ("c", 2)]) 52 small.update([("d", 4), ("e", 5), ("f", 6), ("g", 7), ("h", 8), ("i", 9), ("j", 10), ("k", 11)]) 53 assert.eq(small.keys(), ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"]) 54 55 # duplicate keys are not permitted in dictionary expressions (see b/35698444). 56 assert.fails(lambda: {"aa": 1, "bb": 2, "cc": 3, "bb": 4}, 'duplicate key: "bb"') 57 58 # index 59 def setIndex(d, k, v): 60 d[k] = v 61 62 x9 = {} 63 assert.fails(lambda: x9["a"], 'key "a" not in dict') 64 x9["a"] = 1 65 assert.eq(x9["a"], 1) 66 assert.eq(x9, {"a": 1}) 67 assert.fails(lambda: setIndex(x9, [], 2), 'unhashable type: list') 68 freeze(x9) 69 assert.fails(lambda: setIndex(x9, "a", 3), 'cannot insert into frozen hash table') 70 71 x9a = {} 72 x9a[1, 2] = 3 # unparenthesized tuple is allowed here 73 assert.eq(x9a.keys()[0], (1, 2)) 74 75 # dict.get 76 x10 = {"a": 1} 77 assert.eq(x9.get("a"), 1) 78 assert.eq(x9.get("b"), None) 79 assert.eq(x9.get("a", 2), 1) 80 assert.eq(x9.get("b", 2), 2) 81 82 # dict.clear 83 x11 = {"a": 1} 84 assert.contains(x10, "a") 85 assert.eq(x10["a"], 1) 86 x10.clear() 87 assert.fails(lambda: x10["a"], 'key "a" not in dict') 88 assert.true("a" not in x10) 89 freeze(x10) 90 assert.fails(x10.clear, "cannot clear frozen hash table") 91 92 # dict.setdefault 93 x12 = {"a": 1} 94 assert.eq(x12.setdefault("a"), 1) 95 assert.eq(x12["a"], 1) 96 assert.eq(x12.setdefault("b"), None) 97 assert.eq(x12["b"], None) 98 assert.eq(x12.setdefault("c", 2), 2) 99 assert.eq(x12["c"], 2) 100 assert.eq(x12.setdefault("c", 3), 2) 101 assert.eq(x12["c"], 2) 102 freeze(x12) 103 assert.eq(x12.setdefault("a", 1), 1) # no change, no error 104 assert.fails(lambda: x12.setdefault("d", 1), "cannot insert into frozen hash table") 105 106 # dict.update 107 x13 = {"a": 1} 108 x13.update(a=2, b=3) 109 assert.eq(x13, {"a": 2, "b": 3}) 110 x13.update([("b", 4), ("c", 5)]) 111 assert.eq(x13, {"a": 2, "b": 4, "c": 5}) 112 x13.update({"c": 6, "d": 7}) 113 assert.eq(x13, {"a": 2, "b": 4, "c": 6, "d": 7}) 114 freeze(x13) 115 assert.fails(lambda: x13.update({"a": 8}), "cannot insert into frozen hash table") 116 117 # dict as a sequence 118 # 119 # for loop 120 x14 = {1:2, 3:4} 121 def keys(dict): 122 keys = [] 123 for k in dict: keys.append(k) 124 return keys 125 assert.eq(keys(x14), [1, 3]) 126 # 127 # comprehension 128 assert.eq([x for x in x14], [1, 3]) 129 # 130 # varargs 131 def varargs(*args): return args 132 x15 = {"one": 1} 133 assert.eq(varargs(*x15), ("one",)) 134 135 # kwargs parameter does not alias the **kwargs dict 136 def kwargs(**kwargs): return kwargs 137 x16 = kwargs(**x15) 138 assert.eq(x16, x15) 139 x15["two"] = 2 # mutate 140 assert.ne(x16, x15) 141 142 # iterator invalidation 143 def iterator1(): 144 dict = {1:1, 2:1} 145 for k in dict: 146 dict[2*k] = dict[k] 147 assert.fails(iterator1, "insert.*during iteration") 148 149 def iterator2(): 150 dict = {1:1, 2:1} 151 for k in dict: 152 dict.pop(k) 153 assert.fails(iterator2, "delete.*during iteration") 154 155 def iterator3(): 156 def f(d): 157 d[3] = 3 158 dict = {1:1, 2:1} 159 _ = [f(dict) for x in dict] 160 assert.fails(iterator3, "insert.*during iteration") 161 162 # This assignment is not a modification-during-iteration: 163 # the sequence x should be completely iterated before 164 # the assignment occurs. 165 def f(): 166 x = {1:2, 2:4} 167 a, x[0] = x 168 assert.eq(a, 1) 169 assert.eq(x, {1: 2, 2: 4, 0: 2}) 170 f() 171 172 # Regression test for a bug in hashtable.delete 173 def test_delete(): 174 d = {} 175 176 # delete tail first 177 d["one"] = 1 178 d["two"] = 2 179 assert.eq(str(d), '{"one": 1, "two": 2}') 180 d.pop("two") 181 assert.eq(str(d), '{"one": 1}') 182 d.pop("one") 183 assert.eq(str(d), '{}') 184 185 # delete head first 186 d["one"] = 1 187 d["two"] = 2 188 assert.eq(str(d), '{"one": 1, "two": 2}') 189 d.pop("one") 190 assert.eq(str(d), '{"two": 2}') 191 d.pop("two") 192 assert.eq(str(d), '{}') 193 194 # delete middle 195 d["one"] = 1 196 d["two"] = 2 197 d["three"] = 3 198 assert.eq(str(d), '{"one": 1, "two": 2, "three": 3}') 199 d.pop("two") 200 assert.eq(str(d), '{"one": 1, "three": 3}') 201 d.pop("three") 202 assert.eq(str(d), '{"one": 1}') 203 d.pop("one") 204 assert.eq(str(d), '{}') 205 206 test_delete() 207 208 --- 209 # Verify position of an "unhashable key" error in a dict literal. 210 211 _ = { 212 "one": 1, 213 ["two"]: 2, ### "unhashable type: list" 214 "three": 3, 215 } 216 217 --- 218 # Verify position of a "duplicate key" error in a dict literal. 219 220 _ = { 221 "one": 1, 222 "one": 1, ### `duplicate key: "one"` 223 "three": 3, 224 } 225 226 --- 227 # Verify position of an "unhashable key" error in a dict comprehension. 228 229 _ = { 230 k: v ### "unhashable type: list" 231 for k, v in [ 232 ("one", 1), 233 (["two"], 2), 234 ("three", 3), 235 ] 236 }