github.com/google/skylark@v0.0.0-20181101142754-a5f7082aabed/testdata/assign.sky (about) 1 # Tests of Skylark assignment. 2 3 # This is a "chunked" file: each "---" effectively starts a new file. 4 5 # tuple assignment 6 load("assert.sky", "assert") 7 8 a, b, c = 1, 2, 3 9 assert.eq(a, 1) 10 assert.eq(b, 2) 11 assert.eq(c, 3) 12 13 def f1(): (x,) = 1 14 assert.fails(f1, "int in sequence assignment") 15 def f2(): a, b, c = 1, 2 16 assert.fails(f2, "too few values to unpack") 17 def f3(): a, b = 1, 2, 3 18 assert.fails(f3, "too many values to unpack") 19 def f4(): a, b = (1,) 20 assert.fails(f4, "too few values to unpack") 21 def f5(): (a,) = [1, 2, 3] 22 assert.fails(f5, "too many values to unpack") 23 24 --- 25 # list assignment 26 load("assert.sky", "assert") 27 28 [a, b, c] = [1, 2, 3] 29 assert.eq(a, 1) 30 assert.eq(b, 2) 31 assert.eq(c, 3) 32 33 def f1(): [a, b, c,] = 1 34 assert.fails(f1, "got int in sequence assignment") 35 def f2(): [a, b, c] = 1, 2 36 assert.fails(f2, "too few values to unpack") 37 def f3(): [a, b] = 1, 2, 3 38 assert.fails(f3, "too many values to unpack") 39 def f4(): [a, b] = (1,) 40 assert.fails(f4, "too few values to unpack") 41 42 --- 43 # list-tuple assignment 44 load("assert.sky", "assert") 45 46 [a, b, c] = (1, 2, 3) 47 assert.eq(a, 1) 48 assert.eq(b, 2) 49 assert.eq(c, 3) 50 51 (d, e, f) = [1, 2, 3] 52 assert.eq(d, 1) 53 assert.eq(e, 2) 54 assert.eq(f, 3) 55 56 [g, h, (i, j)] = (1, 2, [3, 4]) 57 assert.eq(g, 1) 58 assert.eq(h, 2) 59 assert.eq(i, 3) 60 assert.eq(j, 4) 61 62 (k, l, [m, n]) = [1, 2, (3, 4)] 63 assert.eq(k, 1) 64 assert.eq(l, 2) 65 assert.eq(m, 3) 66 assert.eq(n, 4) 67 68 --- 69 # misc assignment 70 load("assert.sky", "assert") 71 72 def assignment(): 73 a = [1, 2, 3] 74 a[1] = 5 75 assert.eq(a, [1, 5, 3]) 76 a[-2] = 2 77 assert.eq(a, [1, 2, 3]) 78 assert.eq("%d %d" % (5, 7), "5 7") 79 x={} 80 x[1] = 2 81 x[1] += 3 82 assert.eq(x[1], 5) 83 def f12(): x[(1, "abc", {})] = 1 84 assert.fails(f12, "unhashable type: dict") 85 86 assignment() 87 88 --- 89 # augmented assignment 90 91 load("assert.sky", "assert") 92 93 def f(): 94 x = 1 95 x += 1 96 assert.eq(x, 2) 97 x *= 3 98 assert.eq(x, 6) 99 f() 100 101 --- 102 # effects of evaluating LHS occur only once 103 104 load("assert.sky", "assert") 105 106 count = [0] # count[0] is the number of calls to f 107 108 def f(): 109 count[0] += 1 110 return count[0] 111 112 x = [1, 2, 3] 113 x[f()] += 1 114 115 assert.eq(x, [1, 3, 3]) # sole call to f returned 1 116 assert.eq(count[0], 1) # f was called only once 117 118 --- 119 # Order of evaluation. 120 121 load("assert.sky", "assert") 122 123 calls = [] 124 125 def f(name, result): 126 calls.append(name) 127 return result 128 129 # The right side is evaluated before the left in an ordinary assignment. 130 calls.clear() 131 f("array", [0])[f("index", 0)] = f("rhs", 0) 132 assert.eq(calls, ["rhs", "array", "index"]) 133 134 calls.clear() 135 f("lhs1", [0])[0], f("lhs2", [0])[0] = f("rhs1", 0), f("rhs2", 0) 136 assert.eq(calls, ["rhs1", "rhs2", "lhs1", "lhs2"]) 137 138 # Left side is evaluated first (and only once) in an augmented assignment. 139 calls.clear() 140 f("array", [0])[f("index", 0)] += f("addend", 1) 141 assert.eq(calls, ["array", "index", "addend"]) 142 143 --- 144 # global referenced before assignment 145 146 def f(): 147 return g ### "global variable g referenced before assignment" 148 149 f() 150 151 g = 1 152 153 --- 154 # free variable captured before assignment 155 156 def f(): 157 def g(): ### "local variable outer referenced before assignment" 158 return outer 159 outer = 1 160 161 f() 162 163 --- 164 load("assert.sky", "assert") 165 166 printok = [False] 167 168 # This program should resolve successfully but fail dynamically. 169 # However, the Java implementation currently reports the dynamic 170 # error at the x=1 statement (b/33975425). I think we need to simplify 171 # the resolver algorithm to what we have implemented. 172 def use_before_def(): 173 print(x) # dynamic error: local var referenced before assignment 174 printok[0] = True 175 x = 1 # makes 'x' local 176 177 assert.fails(use_before_def, 'local variable x referenced before assignment') 178 assert.true(not printok[0]) # execution of print statement failed 179 180 --- 181 x = [1] 182 x.extend([2]) # ok 183 184 def f(): 185 x += [4] ### "local variable x referenced before assignment" 186 187 f() 188 189 --- 190 191 z += 3 ### "global variable z referenced before assignment" 192 193 --- 194 load("assert.sky", "assert") 195 196 # It's ok to define a global that shadows a built-in... 197 list = [] 198 assert.eq(type(list), "list") 199 200 # ...but then all uses refer to the global, 201 # even if they occur before the binding use. 202 # See github.com/google/skylark/issues/116. 203 assert.fails(lambda: tuple, "global variable tuple referenced before assignment") 204 tuple = () 205 206 --- 207 # Same as above, but set and float are dialect-specific; 208 # we shouldn't notice any difference. 209 load("assert.sky", "assert") 210 211 float = 1.0 212 assert.eq(type(float), "float") 213 214 set = [1, 2, 3] 215 assert.eq(type(set), "list") 216 217 # As in Python 2 and Python 3, 218 # all 'in x' expressions in a comprehension are evaluated 219 # in the comprehension's lexical block, except the first, 220 # which is resolved in the outer block. 221 x = [[1, 2]] 222 assert.eq([x for x in x for y in x], 223 [[1, 2], [1, 2]]) 224 225 --- 226 # A comprehension establishes a single new lexical block, 227 # not one per 'for' clause. 228 x = [1, 2] 229 _ = [x for _ in [3] for x in x] ### "local variable x referenced before assignment" 230 231 --- 232 load("assert.sky", "assert") 233 234 # assign singleton sequence to 1-tuple 235 (x,) = (1,) 236 assert.eq(x, 1) 237 (y,) = [1] 238 assert.eq(y, 1) 239 240 # assign 1-tuple to variable 241 z = (1,) 242 assert.eq(type(z), "tuple") 243 assert.eq(len(z), 1) 244 assert.eq(z[0], 1) 245 246 --- 247 # assignment to/from fields. 248 load("assert.sky", "assert", "freeze") 249 250 hf = hasfields() 251 hf.x = 1 252 assert.eq(hf.x, 1) 253 hf.x = [1, 2] 254 hf.x += [3, 4] 255 assert.eq(hf.x, [1, 2, 3, 4]) 256 freeze(hf) 257 def setX(hf): 258 hf.x = 2 259 def setY(hf): 260 hf.y = 3 261 assert.fails(lambda: setX(hf), "cannot set field on a frozen hasfields") 262 assert.fails(lambda: setY(hf), "cannot set field on a frozen hasfields") 263 264 --- 265 # destucturing assignment in a for loop. 266 load("assert.sky", "assert") 267 268 def f(): 269 res = [] 270 for (x, y), z in [(["a", "b"], 3), (["c", "d"], 4)]: 271 res.append((x, y, z)) 272 return res 273 assert.eq(f(), [("a", "b", 3), ("c", "d", 4)]) 274 275 def g(): 276 a = {} 277 for i, a[i] in [("one", 1), ("two", 2)]: 278 pass 279 return a 280 assert.eq(g(), {"one": 1, "two": 2})