github.com/k14s/starlark-go@v0.0.0-20200720175618-3a5c849cc368/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. (option:lambda option:nesteddef) 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 # return statements must be within a function 147 148 return ### "return statement not within a function" 149 150 --- 151 # if-statements and for-loops at top-level are forbidden 152 # (without globalreassign option) 153 154 for x in "abc": ### "for loop not within a function" 155 pass 156 157 if x: ### "if statement not within a function" 158 pass 159 160 --- 161 # option:globalreassign 162 163 for x in "abc": # ok 164 pass 165 166 if x: # ok 167 pass 168 169 --- 170 # while loops are forbidden (without -recursion option) 171 172 def f(): 173 while U: ### "dialect does not support while loops" 174 pass 175 176 --- 177 # option:recursion 178 179 def f(): 180 while U: # ok 181 pass 182 183 while U: ### "while loop not within a function" 184 pass 185 186 --- 187 # option:globalreassign option:recursion 188 189 while U: # ok 190 pass 191 192 --- 193 # The parser allows any expression on the LHS of an assignment. 194 195 1 = 0 ### "can't assign to literal" 196 1+2 = 0 ### "can't assign to binaryexpr" 197 f() = 0 ### "can't assign to callexpr" 198 199 [a, b] = 0 200 [c, d] += 0 ### "can't use list expression in augmented assignment" 201 (e, f) += 0 ### "can't use tuple expression in augmented assignment" 202 [] = 0 ### "can't assign to \\[\\]" 203 () = 0 ### "can't assign to ()" 204 205 --- 206 # break and continue statements must appear within a loop 207 208 break ### "break not in a loop" 209 210 continue ### "continue not in a loop" 211 212 pass 213 214 --- 215 # Positional arguments (and required parameters) 216 # must appear before named arguments (and optional parameters). 217 218 M(x=1, 2) ### `positional argument may not follow named` 219 220 def f(x=1, y): pass ### `required parameter may not follow optional` 221 --- 222 # No parameters may follow **kwargs in a declaration. 223 224 def f(**kwargs, x): ### `parameter may not follow \*\*kwargs` 225 pass 226 227 def g(**kwargs, *args): ### `\* parameter may not follow \*\*kwargs` 228 pass 229 230 def h(**kwargs1, **kwargs2): ### `multiple \*\* parameters not allowed` 231 pass 232 233 --- 234 # Only keyword-only params and **kwargs may follow *args in a declaration. 235 236 def f(*args, x): # ok 237 pass 238 239 def g(*args1, *args2): ### `multiple \* parameters not allowed` 240 pass 241 242 def h(*, ### `bare \* must be followed by keyword-only parameters` 243 *): ### `multiple \* parameters not allowed` 244 pass 245 246 def i(*args, *): ### `multiple \* parameters not allowed` 247 pass 248 249 def j(*, ### `bare \* must be followed by keyword-only parameters` 250 *args): ### `multiple \* parameters not allowed` 251 pass 252 253 def k(*, **kwargs): ### `bare \* must be followed by keyword-only parameters` 254 pass 255 256 def l(*): ### `bare \* must be followed by keyword-only parameters` 257 pass 258 259 def m(*args, a=1, **kwargs): # ok 260 pass 261 262 def n(*, a=1, **kwargs): # ok 263 pass 264 265 --- 266 # No arguments may follow **kwargs in a call. 267 def f(*args, **kwargs): 268 pass 269 270 f(**{}, 1) ### `argument may not follow \*\*kwargs` 271 f(**{}, x=1) ### `argument may not follow \*\*kwargs` 272 f(**{}, *[]) ### `\*args may not follow \*\*kwargs` 273 f(**{}, **{}) ### `multiple \*\*kwargs not allowed` 274 275 --- 276 # Only keyword arguments may follow *args in a call. 277 def f(*args, **kwargs): 278 pass 279 280 f(*[], 1) ### `argument may not follow \*args` 281 f(*[], a=1) # ok 282 f(*[], *[]) ### `multiple \*args not allowed` 283 f(*[], **{}) # ok 284 285 --- 286 # Parameter names must be unique. 287 288 def f(a, b, a): pass ### "duplicate parameter: a" 289 def g(args, b, *args): pass ### "duplicate parameter: args" 290 def h(kwargs, a, **kwargs): pass ### "duplicate parameter: kwargs" 291 def i(*x, **x): pass ### "duplicate parameter: x" 292 293 --- 294 # No floating point 295 a = float("3.141") ### `dialect does not support floating point` 296 b = 1 / 2 ### `dialect does not support floating point \(use //\)` 297 c = 3.141 ### `dialect does not support floating point` 298 --- 299 # Floating point support (option:float) 300 a = float("3.141") 301 b = 1 / 2 302 c = 3.141 303 304 --- 305 # option:globalreassign 306 # Legacy Bazel (and Python) semantics: def must precede use even for globals. 307 308 _ = x ### `undefined: x` 309 x = 1 310 311 --- 312 # option:globalreassign 313 # Legacy Bazel (and Python) semantics: reassignment of globals is allowed. 314 x = 1 315 x = 2 # ok 316 317 --- 318 # option:globalreassign 319 # Redeclaration of predeclared names is allowed. 320 321 # module-specific predeclared name 322 M = 1 # ok 323 M = 2 # ok (legacy) 324 325 # universal predeclared name 326 U = 1 # ok 327 U = 1 # ok (legacy) 328 329 --- 330 # https://github.com/bazelbuild/starlark/starlark/issues/21 331 def f(**kwargs): pass 332 f(a=1, a=1) ### `keyword argument a repeated` 333 334 335 --- 336 # spelling 337 338 print = U 339 340 hello = 1 341 print(hollo) ### `undefined: hollo \(did you mean hello\?\)` 342 343 def f(abc): 344 print(abd) ### `undefined: abd \(did you mean abc\?\)` 345 print(goodbye) ### `undefined: goodbye$` 346 347 --- 348 load("module", "x") # ok 349 x = 1 ### `cannot reassign local x` 350 load("module", "x") ### `cannot reassign top-level x` 351 352 --- 353 # option:loadbindsglobally 354 load("module", "x") # ok 355 x = 1 ### `cannot reassign global x` 356 load("module", "x") ### `cannot reassign global x` 357 358 --- 359 # option:globalreassign 360 load("module", "x") # ok 361 x = 1 # ok 362 load("module", "x") # ok 363 364 --- 365 # option:globalreassign option:loadbindsglobally 366 load("module", "x") # ok 367 x = 1 368 load("module", "x") # ok 369 370 --- 371 _ = x # forward ref to file-local 372 load("module", "x") # ok