go.starlark.net@v0.0.0-20231101134539-556fd59b42f6/resolve/testdata/resolve.star (about) 1 # Tests of resolver errors. 2 # 3 # The initial environment contains the predeclared names "M" 4 # (module-specific) and "U" (universal). This distinction 5 # should be unobservable to the Starlark program. 6 7 # use of declared global 8 x = 1 9 _ = x 10 11 --- 12 # premature use of global is not a static error; 13 # see github.com/google/skylark/issues/116. 14 _ = x 15 x = 1 16 17 --- 18 # use of undefined global 19 _ = x ### "undefined: x" 20 21 --- 22 # redeclaration of global 23 x = 1 24 x = 2 ### "cannot reassign global x declared at .*resolve.star:23:1" 25 26 --- 27 # Redeclaration of predeclared names is allowed. 28 # 29 # This rule permits tool maintainers to add members to the predeclared 30 # environment without breaking existing programs. 31 32 # module-specific predeclared name 33 M = 1 # ok 34 M = 2 ### "cannot reassign global M declared at .*/resolve.star" 35 36 # universal predeclared name 37 U = 1 # ok 38 U = 1 ### "cannot reassign global U declared at .*/resolve.star" 39 40 --- 41 # A global declaration shadows all references to a predeclared; 42 # see github.com/google/skylark/issues/116. 43 44 a = U # ok: U is a reference to the global defined on the next line. 45 U = 1 46 47 --- 48 # reference to predeclared name 49 M() 50 51 --- 52 # locals may be referenced before they are defined 53 54 def f(): 55 M(x) # dynamic error 56 x = 1 57 58 --- 59 # Various forms of assignment: 60 61 def f(x): # parameter 62 M(x) 63 M(y) ### "undefined: y" 64 65 (a, b) = 1, 2 66 M(a) 67 M(b) 68 M(c) ### "undefined: c" 69 70 [p, q] = 1, 2 71 M(p) 72 M(q) 73 M(r) ### "undefined: r" 74 75 --- 76 # a comprehension introduces a separate lexical block 77 78 _ = [x for x in "abc"] 79 M(x) ### "undefined: x" 80 81 --- 82 # Functions may have forward refs. 83 def f(): 84 g() 85 h() ### "undefined: h" 86 def inner(): 87 i() 88 i = lambda: 0 89 90 def g(): 91 f() 92 93 --- 94 # It is not permitted to rebind a global using a += assignment. 95 96 x = [1] 97 x.extend([2]) # ok 98 x += [3] ### `cannot reassign global x` 99 100 def f(): 101 x += [4] # x is local to f 102 103 y = 1 104 y += 2 ### `cannot reassign global y` 105 z += 3 # ok (but fails dynamically because z is undefined) 106 107 --- 108 def f(a): 109 if 1==1: 110 b = 1 111 c = 1 112 M(a) # ok: param 113 M(b) # ok: maybe bound local 114 M(c) # ok: bound local 115 M(d) # NB: we don't do a use-before-def check on local vars! 116 M(e) # ok: global 117 M(f) # ok: global 118 d = 1 119 120 e = 1 121 122 --- 123 # This program should resolve successfully but fail dynamically. 124 x = 1 125 126 def f(): 127 M(x) # dynamic error: reference to undefined local 128 x = 2 129 130 f() 131 132 --- 133 load("module", "name") # ok 134 135 def f(): 136 load("foo", "bar") ### "load statement within a function" 137 138 load("foo", 139 "", ### "load: empty identifier" 140 "_a", ### "load: names with leading underscores are not exported: _a" 141 b="", ### "load: empty identifier" 142 c="_d", ### "load: names with leading underscores are not exported: _d" 143 _e="f") # ok 144 145 --- 146 # option:toplevelcontrol 147 if M: 148 load("foo", "bar") ### "load statement within a conditional" 149 150 --- 151 # option:toplevelcontrol 152 for x in M: 153 load("foo", "bar") ### "load statement within a loop" 154 155 --- 156 # option:toplevelcontrol option:while 157 while M: 158 load("foo", "bar") ### "load statement within a loop" 159 160 --- 161 # return statements must be within a function 162 163 return ### "return statement not within a function" 164 165 --- 166 # if-statements and for-loops at top-level are forbidden 167 # (without globalreassign option) 168 169 for x in "abc": ### "for loop not within a function" 170 pass 171 172 if x: ### "if statement not within a function" 173 pass 174 175 --- 176 # option:toplevelcontrol 177 178 for x in "abc": # ok 179 pass 180 181 if x: # ok 182 pass 183 184 --- 185 # while loops are forbidden (without -recursion option) 186 187 def f(): 188 while U: ### "dialect does not support while loops" 189 pass 190 191 --- 192 # option:while 193 194 def f(): 195 while U: # ok 196 pass 197 198 while U: ### "while loop not within a function" 199 pass 200 201 --- 202 # option:toplevelcontrol option:while 203 204 while U: # ok 205 pass 206 207 --- 208 # The parser allows any expression on the LHS of an assignment. 209 210 1 = 0 ### "can't assign to literal" 211 1+2 = 0 ### "can't assign to binaryexpr" 212 f() = 0 ### "can't assign to callexpr" 213 214 [a, b] = 0 215 [c, d] += 0 ### "can't use list expression in augmented assignment" 216 (e, f) += 0 ### "can't use tuple expression in augmented assignment" 217 218 [] = 0 # ok 219 () = 0 # ok 220 221 --- 222 # break and continue statements must appear within a loop 223 224 break ### "break not in a loop" 225 226 continue ### "continue not in a loop" 227 228 pass 229 230 --- 231 # Positional arguments (and required parameters) 232 # must appear before named arguments (and optional parameters). 233 234 M(x=1, 2) ### `positional argument may not follow named` 235 236 def f(x=1, y): pass ### `required parameter may not follow optional` 237 --- 238 # No parameters may follow **kwargs in a declaration. 239 240 def f(**kwargs, x): ### `parameter may not follow \*\*kwargs` 241 pass 242 243 def g(**kwargs, *args): ### `\* parameter may not follow \*\*kwargs` 244 pass 245 246 def h(**kwargs1, **kwargs2): ### `multiple \*\* parameters not allowed` 247 pass 248 249 --- 250 # Only keyword-only params and **kwargs may follow *args in a declaration. 251 252 def f(*args, x): # ok 253 pass 254 255 def g(*args1, *args2): ### `multiple \* parameters not allowed` 256 pass 257 258 def h(*, ### `bare \* must be followed by keyword-only parameters` 259 *): ### `multiple \* parameters not allowed` 260 pass 261 262 def i(*args, *): ### `multiple \* parameters not allowed` 263 pass 264 265 def j(*, ### `bare \* must be followed by keyword-only parameters` 266 *args): ### `multiple \* parameters not allowed` 267 pass 268 269 def k(*, **kwargs): ### `bare \* must be followed by keyword-only parameters` 270 pass 271 272 def l(*): ### `bare \* must be followed by keyword-only parameters` 273 pass 274 275 def m(*args, a=1, **kwargs): # ok 276 pass 277 278 def n(*, a=1, **kwargs): # ok 279 pass 280 281 --- 282 # No arguments may follow **kwargs in a call. 283 def f(*args, **kwargs): 284 pass 285 286 f(**{}, 1) ### `argument may not follow \*\*kwargs` 287 f(**{}, x=1) ### `argument may not follow \*\*kwargs` 288 f(**{}, *[]) ### `\*args may not follow \*\*kwargs` 289 f(**{}, **{}) ### `multiple \*\*kwargs not allowed` 290 291 --- 292 # Only **kwargs may follow *args in a call. 293 def f(*args, **kwargs): 294 pass 295 296 f(*[], 1) ### `positional argument may not follow \*args` 297 f(*[], a=1) ### `keyword argument may not follow \*args` 298 f(*[], *[]) ### `multiple \*args not allowed` 299 f(*[], **{}) # ok 300 301 --- 302 # Parameter names must be unique. 303 304 def f(a, b, a): pass ### "duplicate parameter: a" 305 def g(args, b, *args): pass ### "duplicate parameter: args" 306 def h(kwargs, a, **kwargs): pass ### "duplicate parameter: kwargs" 307 def i(*x, **x): pass ### "duplicate parameter: x" 308 309 --- 310 # Floating-point support is now standard. 311 a = float("3.141") 312 b = 1 / 2 313 c = 3.141 314 315 --- 316 # option:globalreassign 317 # Legacy Bazel (and Python) semantics: def must precede use even for globals. 318 319 _ = x ### `undefined: x` 320 x = 1 321 322 --- 323 # option:globalreassign 324 # Legacy Bazel (and Python) semantics: reassignment of globals is allowed. 325 x = 1 326 x = 2 # ok 327 328 --- 329 # option:globalreassign 330 # Redeclaration of predeclared names is allowed. 331 332 # module-specific predeclared name 333 M = 1 # ok 334 M = 2 # ok (legacy) 335 336 # universal predeclared name 337 U = 1 # ok 338 U = 1 # ok (legacy) 339 340 --- 341 # https://github.com/bazelbuild/starlark/starlark/issues/21 342 def f(**kwargs): pass 343 f(a=1, a=1) ### `keyword argument "a" is repeated` 344 345 346 --- 347 # spelling 348 349 print = U 350 351 hello = 1 352 print(hollo) ### `undefined: hollo \(did you mean hello\?\)` 353 354 def f(abc): 355 print(abd) ### `undefined: abd \(did you mean abc\?\)` 356 print(goodbye) ### `undefined: goodbye$` 357 358 --- 359 load("module", "x") # ok 360 x = 1 ### `cannot reassign local x` 361 load("module", "x") ### `cannot reassign top-level x` 362 363 --- 364 # option:loadbindsglobally 365 load("module", "x") # ok 366 x = 1 ### `cannot reassign global x` 367 load("module", "x") ### `cannot reassign global x` 368 369 --- 370 # option:globalreassign 371 load("module", "x") # ok 372 x = 1 # ok 373 load("module", "x") # ok 374 375 --- 376 # option:globalreassign option:loadbindsglobally 377 load("module", "x") # ok 378 x = 1 379 load("module", "x") # ok 380 381 --- 382 _ = x # forward ref to file-local 383 load("module", "x") # ok