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