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 8x = 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 15x = 1 16 17--- 18# use of undefined global 19_ = x ### "undefined: x" 20 21--- 22# redeclaration of global 23x = 1 24x = 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 33M = 1 # ok 34M = 2 ### "cannot reassign global M declared at .*/resolve.star" 35 36# universal predeclared name 37U = 1 # ok 38U = 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 44a = U # ok: U is a reference to the global defined on the next line. 45U = 1 46 47--- 48# reference to predeclared name 49M() 50 51--- 52# locals may be referenced before they are defined 53 54def f(): 55 M(x) # dynamic error 56 x = 1 57 58--- 59# Various forms of assignment: 60 61def f(x): # parameter 62 M(x) 63 M(y) ### "undefined: y" 64 65(a, b) = 1, 2 66M(a) 67M(b) 68M(c) ### "undefined: c" 69 70[p, q] = 1, 2 71M(p) 72M(q) 73M(r) ### "undefined: r" 74 75--- 76# a comprehension introduces a separate lexical block 77 78_ = [x for x in "abc"] 79M(x) ### "undefined: x" 80 81--- 82# Functions may have forward refs. 83def f(): 84 g() 85 h() ### "undefined: h" 86 def inner(): 87 i() 88 i = lambda: 0 89 90def g(): 91 f() 92 93--- 94# It is not permitted to rebind a global using a += assignment. 95 96x = [1] 97x.extend([2]) # ok 98x += [3] ### `cannot reassign global x` 99 100def f(): 101 x += [4] # x is local to f 102 103y = 1 104y += 2 ### `cannot reassign global y` 105z += 3 # ok (but fails dynamically because z is undefined) 106 107--- 108def 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 120e = 1 121 122--- 123# This program should resolve successfully but fail dynamically. 124x = 1 125 126def f(): 127 M(x) # dynamic error: reference to undefined local 128 x = 2 129 130f() 131 132--- 133load("module", "name") # ok 134 135def f(): 136 load("foo", "bar") ### "load statement within a function" 137 138load("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:globalreassign 147if M: 148 load("foo", "bar") ### "load statement within a conditional" 149 150--- 151# option:globalreassign 152for x in M: 153 load("foo", "bar") ### "load statement within a loop" 154 155--- 156# option:recursion option:globalreassign 157while M: 158 load("foo", "bar") ### "load statement within a loop" 159 160--- 161# return statements must be within a function 162 163return ### "return statement not within a function" 164 165--- 166# if-statements and for-loops at top-level are forbidden 167# (without globalreassign option) 168 169for x in "abc": ### "for loop not within a function" 170 pass 171 172if x: ### "if statement not within a function" 173 pass 174 175--- 176# option:globalreassign 177 178for x in "abc": # ok 179 pass 180 181if x: # ok 182 pass 183 184--- 185# while loops are forbidden (without -recursion option) 186 187def f(): 188 while U: ### "dialect does not support while loops" 189 pass 190 191--- 192# option:recursion 193 194def f(): 195 while U: # ok 196 pass 197 198while U: ### "while loop not within a function" 199 pass 200 201--- 202# option:globalreassign option:recursion 203 204while U: # ok 205 pass 206 207--- 208# The parser allows any expression on the LHS of an assignment. 209 2101 = 0 ### "can't assign to literal" 2111+2 = 0 ### "can't assign to binaryexpr" 212f() = 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 224break ### "break not in a loop" 225 226continue ### "continue not in a loop" 227 228pass 229 230--- 231# Positional arguments (and required parameters) 232# must appear before named arguments (and optional parameters). 233 234M(x=1, 2) ### `positional argument may not follow named` 235 236def f(x=1, y): pass ### `required parameter may not follow optional` 237--- 238# No parameters may follow **kwargs in a declaration. 239 240def f(**kwargs, x): ### `parameter may not follow \*\*kwargs` 241 pass 242 243def g(**kwargs, *args): ### `\* parameter may not follow \*\*kwargs` 244 pass 245 246def 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 252def f(*args, x): # ok 253 pass 254 255def g(*args1, *args2): ### `multiple \* parameters not allowed` 256 pass 257 258def h(*, ### `bare \* must be followed by keyword-only parameters` 259 *): ### `multiple \* parameters not allowed` 260 pass 261 262def i(*args, *): ### `multiple \* parameters not allowed` 263 pass 264 265def j(*, ### `bare \* must be followed by keyword-only parameters` 266 *args): ### `multiple \* parameters not allowed` 267 pass 268 269def k(*, **kwargs): ### `bare \* must be followed by keyword-only parameters` 270 pass 271 272def l(*): ### `bare \* must be followed by keyword-only parameters` 273 pass 274 275def m(*args, a=1, **kwargs): # ok 276 pass 277 278def n(*, a=1, **kwargs): # ok 279 pass 280 281--- 282# No arguments may follow **kwargs in a call. 283def f(*args, **kwargs): 284 pass 285 286f(**{}, 1) ### `argument may not follow \*\*kwargs` 287f(**{}, x=1) ### `argument may not follow \*\*kwargs` 288f(**{}, *[]) ### `\*args may not follow \*\*kwargs` 289f(**{}, **{}) ### `multiple \*\*kwargs not allowed` 290 291--- 292# Only **kwargs may follow *args in a call. 293def f(*args, **kwargs): 294 pass 295 296f(*[], 1) ### `positional argument may not follow \*args` 297f(*[], a=1) ### `keyword argument may not follow \*args` 298f(*[], *[]) ### `multiple \*args not allowed` 299f(*[], **{}) # ok 300 301--- 302# Parameter names must be unique. 303 304def f(a, b, a): pass ### "duplicate parameter: a" 305def g(args, b, *args): pass ### "duplicate parameter: args" 306def h(kwargs, a, **kwargs): pass ### "duplicate parameter: kwargs" 307def i(*x, **x): pass ### "duplicate parameter: x" 308 309--- 310# Floating-point support is now standard. 311a = float("3.141") 312b = 1 / 2 313c = 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` 320x = 1 321 322--- 323# option:globalreassign 324# Legacy Bazel (and Python) semantics: reassignment of globals is allowed. 325x = 1 326x = 2 # ok 327 328--- 329# option:globalreassign 330# Redeclaration of predeclared names is allowed. 331 332# module-specific predeclared name 333M = 1 # ok 334M = 2 # ok (legacy) 335 336# universal predeclared name 337U = 1 # ok 338U = 1 # ok (legacy) 339 340--- 341# https://github.com/bazelbuild/starlark/starlark/issues/21 342def f(**kwargs): pass 343f(a=1, a=1) ### `keyword argument a repeated` 344 345 346--- 347# spelling 348 349print = U 350 351hello = 1 352print(hollo) ### `undefined: hollo \(did you mean hello\?\)` 353 354def f(abc): 355 print(abd) ### `undefined: abd \(did you mean abc\?\)` 356 print(goodbye) ### `undefined: goodbye$` 357 358--- 359load("module", "x") # ok 360x = 1 ### `cannot reassign local x` 361load("module", "x") ### `cannot reassign top-level x` 362 363--- 364# option:loadbindsglobally 365load("module", "x") # ok 366x = 1 ### `cannot reassign global x` 367load("module", "x") ### `cannot reassign global x` 368 369--- 370# option:globalreassign 371load("module", "x") # ok 372x = 1 # ok 373load("module", "x") # ok 374 375--- 376# option:globalreassign option:loadbindsglobally 377load("module", "x") # ok 378x = 1 379load("module", "x") # ok 380 381--- 382_ = x # forward ref to file-local 383load("module", "x") # ok 384