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