github.com/k14s/starlark-go@v0.0.0-20200720175618-3a5c849cc368/starlark/testdata/assign.star (about) 1 # Tests of Starlark assignment. 2 3 # This is a "chunked" file: each "---" effectively starts a new file. 4 5 # tuple assignment 6 load("assert.star", "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.star", "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.star", "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 # option:nesteddef 70 # misc assignment 71 load("assert.star", "assert") 72 73 def assignment(): 74 a = [1, 2, 3] 75 a[1] = 5 76 assert.eq(a, [1, 5, 3]) 77 a[-2] = 2 78 assert.eq(a, [1, 2, 3]) 79 assert.eq("%d %d" % (5, 7), "5 7") 80 x={} 81 x[1] = 2 82 x[1] += 3 83 assert.eq(x[1], 5) 84 def f12(): x[(1, "abc", {})] = 1 85 assert.fails(f12, "unhashable type: dict") 86 87 assignment() 88 89 --- 90 # augmented assignment 91 92 load("assert.star", "assert") 93 94 def f(): 95 x = 1 96 x += 1 97 assert.eq(x, 2) 98 x *= 3 99 assert.eq(x, 6) 100 f() 101 102 --- 103 # effects of evaluating LHS occur only once 104 105 load("assert.star", "assert") 106 107 count = [0] # count[0] is the number of calls to f 108 109 def f(): 110 count[0] += 1 111 return count[0] 112 113 x = [1, 2, 3] 114 x[f()] += 1 115 116 assert.eq(x, [1, 3, 3]) # sole call to f returned 1 117 assert.eq(count[0], 1) # f was called only once 118 119 --- 120 # Order of evaluation. 121 122 load("assert.star", "assert") 123 124 calls = [] 125 126 def f(name, result): 127 calls.append(name) 128 return result 129 130 # The right side is evaluated before the left in an ordinary assignment. 131 calls.clear() 132 f("array", [0])[f("index", 0)] = f("rhs", 0) 133 assert.eq(calls, ["rhs", "array", "index"]) 134 135 calls.clear() 136 f("lhs1", [0])[0], f("lhs2", [0])[0] = f("rhs1", 0), f("rhs2", 0) 137 assert.eq(calls, ["rhs1", "rhs2", "lhs1", "lhs2"]) 138 139 # Left side is evaluated first (and only once) in an augmented assignment. 140 calls.clear() 141 f("array", [0])[f("index", 0)] += f("addend", 1) 142 assert.eq(calls, ["array", "index", "addend"]) 143 144 --- 145 # global referenced before assignment 146 147 def f(): 148 return g ### "global variable g referenced before assignment" 149 150 f() 151 152 g = 1 153 154 --- 155 # option:nesteddef 156 # Free variables are captured by reference, so this is ok. 157 load("assert.star", "assert") 158 159 def f(): 160 def g(): 161 return outer 162 outer = 1 163 return g() 164 165 assert.eq(f(), 1) 166 167 --- 168 load("assert.star", "assert") 169 170 printok = [False] 171 172 # This program should resolve successfully but fail dynamically. 173 # However, the Java implementation currently reports the dynamic 174 # error at the x=1 statement (b/33975425). I think we need to simplify 175 # the resolver algorithm to what we have implemented. 176 def use_before_def(): 177 print(x) # dynamic error: local var referenced before assignment 178 printok[0] = True 179 x = 1 # makes 'x' local 180 181 assert.fails(use_before_def, 'local variable x referenced before assignment') 182 assert.true(not printok[0]) # execution of print statement failed 183 184 --- 185 x = [1] 186 x.extend([2]) # ok 187 188 def f(): 189 x += [4] ### "local variable x referenced before assignment" 190 191 f() 192 193 --- 194 195 z += 3 ### "global variable z referenced before assignment" 196 197 --- 198 load("assert.star", "assert") 199 200 # It's ok to define a global that shadows a built-in... 201 list = [] 202 assert.eq(type(list), "list") 203 204 # ...but then all uses refer to the global, 205 # even if they occur before the binding use. 206 # See github.com/google/skylark/issues/116. 207 assert.fails(lambda: tuple, "global variable tuple referenced before assignment") 208 tuple = () 209 210 --- 211 # option:float option:set 212 # Same as above, but set and float are dialect-specific; 213 # we shouldn't notice any difference. 214 load("assert.star", "assert") 215 216 float = 1.0 217 assert.eq(type(float), "float") 218 219 set = [1, 2, 3] 220 assert.eq(type(set), "list") 221 222 # As in Python 2 and Python 3, 223 # all 'in x' expressions in a comprehension are evaluated 224 # in the comprehension's lexical block, except the first, 225 # which is resolved in the outer block. 226 x = [[1, 2]] 227 assert.eq([x for x in x for y in x], 228 [[1, 2], [1, 2]]) 229 230 --- 231 # A comprehension establishes a single new lexical block, 232 # not one per 'for' clause. 233 x = [1, 2] 234 _ = [x for _ in [3] for x in x] ### "local variable x referenced before assignment" 235 236 --- 237 load("assert.star", "assert") 238 239 # assign singleton sequence to 1-tuple 240 (x,) = (1,) 241 assert.eq(x, 1) 242 (y,) = [1] 243 assert.eq(y, 1) 244 245 # assign 1-tuple to variable 246 z = (1,) 247 assert.eq(type(z), "tuple") 248 assert.eq(len(z), 1) 249 assert.eq(z[0], 1) 250 251 # assign value to parenthesized variable 252 (a) = 1 253 assert.eq(a, 1) 254 255 --- 256 # assignment to/from fields. 257 load("assert.star", "assert", "freeze") 258 259 hf = hasfields() 260 hf.x = 1 261 assert.eq(hf.x, 1) 262 hf.x = [1, 2] 263 hf.x += [3, 4] 264 assert.eq(hf.x, [1, 2, 3, 4]) 265 freeze(hf) 266 def setX(hf): 267 hf.x = 2 268 def setY(hf): 269 hf.y = 3 270 assert.fails(lambda: setX(hf), "cannot set field on a frozen hasfields") 271 assert.fails(lambda: setY(hf), "cannot set field on a frozen hasfields") 272 273 --- 274 # destucturing assignment in a for loop. 275 load("assert.star", "assert") 276 277 def f(): 278 res = [] 279 for (x, y), z in [(["a", "b"], 3), (["c", "d"], 4)]: 280 res.append((x, y, z)) 281 return res 282 assert.eq(f(), [("a", "b", 3), ("c", "d", 4)]) 283 284 def g(): 285 a = {} 286 for i, a[i] in [("one", 1), ("two", 2)]: 287 pass 288 return a 289 assert.eq(g(), {"one": 1, "two": 2}) 290 291 --- 292 # parenthesized LHS in augmented assignment (success) 293 # option:globalreassign 294 load("assert.star", "assert") 295 296 a = 5 297 (a) += 3 298 assert.eq(a, 8) 299 300 --- 301 # parenthesized LHS in augmented assignment (error) 302 303 (a) += 5 ### "global variable a referenced before assignment" 304 305 --- 306 # option:globalreassign 307 load("assert.star", "assert") 308 assert = 1 309 load("assert.star", "assert") 310 311 --- 312 # option:globalreassign option:loadbindsglobally 313 load("assert.star", "assert") 314 assert = 1 315 load("assert.star", "assert") 316 317 --- 318 # option:loadbindsglobally 319 _ = assert ### "global variable assert referenced before assignment" 320 load("assert.star", "assert") 321 322 --- 323 _ = assert ### "local variable assert referenced before assignment" 324 load("assert.star", "assert") 325 326 --- 327 def f(): assert.eq(1, 1) # forward ref OK 328 load("assert.star", "assert") 329 f() 330 331 --- 332 # option:loadbindsglobally 333 def f(): assert.eq(1, 1) # forward ref OK 334 load("assert.star", "assert") 335 f()