github.com/google/skylark@v0.0.0-20181101142754-a5f7082aabed/resolve/testdata/resolve.sky (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 Skylark program.
     6  
     7  # use of declared global
     8  x = 1
     9  _ = x
    10  
    11  ---
    12  # premature use of global is not a static error; see issue 116.
    13  _ = x
    14  x = 1
    15  
    16  ---
    17  # use of undefined global
    18  _ = x ### "undefined: x"
    19  
    20  ---
    21  # redeclaration of global
    22  x = 1
    23  x = 2 ### "cannot reassign global x declared at .*resolve.sky:22:1"
    24  
    25  ---
    26  # Redeclaration of predeclared names is allowed.
    27  #
    28  # This rule permits tool maintainers to add members to the predeclared
    29  # environment without breaking existing programs.
    30  
    31  # module-specific predeclared name
    32  M = 1 # ok
    33  M = 2 ### "cannot reassign global M declared at .*/resolve.sky"
    34  
    35  # universal predeclared name
    36  U = 1 # ok
    37  U = 1 ### "cannot reassign global U declared at .*/resolve.sky"
    38  
    39  ---
    40  # A global declaration shadows all references to a predeclared; see issue 116.
    41  
    42  a = U # ok: U is a reference to the global defined on the next line.
    43  U = 1
    44  
    45  ---
    46  # reference to predeclared name
    47  M()
    48  
    49  ---
    50  # locals may be referenced before they are defined
    51  
    52  def f():
    53     M(x) # dynamic error
    54     x = 1
    55  
    56  ---
    57  # Various forms of assignment:
    58  
    59  def f(x): # parameter
    60      M(x)
    61      M(y) ### "undefined: y"
    62  
    63  (a, b) = 1, 2
    64  M(a)
    65  M(b)
    66  M(c) ### "undefined: c"
    67  
    68  [p, q] = 1, 2
    69  M(p)
    70  M(q)
    71  M(r) ### "undefined: r"
    72  
    73  ---
    74  # a comprehension introduces a separate lexical block
    75  
    76  _ = [x for x in "abc"]
    77  M(x) ### "undefined: x"
    78  
    79  ---
    80  # Functions may have forward refs.   (option:lambda option:nesteddef)
    81  def f():
    82     g()
    83     h() ### "undefined: h"
    84     def inner():
    85       i()
    86       i = lambda: 0
    87  
    88  def g():
    89    f()
    90  
    91  ---
    92  # It's permitted to rebind a global using a += assignment.
    93  
    94  x = [1]
    95  x.extend([2]) # ok
    96  x += [3] # ok (a list mutation, not a global rebinding)
    97  
    98  def f():
    99     x += [4] # x is local to f
   100  
   101  y = 1
   102  y += 2 # ok (even though it is in fact a global rebinding)
   103  
   104  z += 3 # ok (but fails dynamically because z is undefined)
   105  
   106  ---
   107  def f(a):
   108    if 1==1:
   109      b = 1
   110    c = 1
   111    M(a) # ok: param
   112    M(b) # ok: maybe bound local
   113    M(c) # ok: bound local
   114    M(d) # NB: we don't do a use-before-def check on local vars!
   115    M(e) # ok: global
   116    M(f) # ok: global
   117    d = 1
   118  
   119  e = 1
   120  
   121  ---
   122  # This program should resolve successfully but fail dynamically.
   123  x = 1
   124  
   125  def f():
   126    M(x) # dynamic error: reference to undefined local
   127    x = 2
   128  
   129  f()
   130  
   131  ---
   132  load("module", "name") # ok
   133  
   134  def f():
   135    load("foo", "bar") ### "load statement within a function"
   136  
   137  load("foo",
   138       "",     ### "load: empty identifier"
   139       "_a",   ### "load: names with leading underscores are not exported: _a"
   140       b="",   ### "load: empty identifier"
   141       c="_d", ### "load: names with leading underscores are not exported: _d"
   142       _e="f") # ok
   143  
   144  ---
   145  # return, if statements and for loops at top-level are forbidden
   146  
   147  for x in "abc": ### "for loop not within a function"
   148    pass
   149  
   150  if x: ### "if statement not within a function"
   151    pass
   152  
   153  return ### "return statement not within a function"
   154  
   155  ---
   156  # The parser allows any expression on the LHS of an assignment.
   157  
   158  1 = 2 ### "can't assign to literal"
   159  1+2 = 3 ### "can't assign to binaryexpr"
   160  f() = 4 ### "can't assign to callexpr"
   161  
   162  [a, b] = [1, 2]
   163  [a, b] += [3, 4] ### "can't use list expression in augmented assignment"
   164  (a, b) += [3, 4] ### "can't use tuple expression in augmented assignment"
   165  [] = [] ### "can't assign to \\[\\]"
   166  () = () ### "can't assign to ()"
   167  
   168  ---
   169  # break and continue statements must appear within a loop
   170  
   171  break ### "break not in a loop"
   172  
   173  continue ### "continue not in a loop"
   174  
   175  pass
   176  
   177  ---
   178  # Positional arguments (and required parameters)
   179  # must appear before named arguments (and optional parameters).
   180  
   181  M(x=1, 2) ### `positional argument may not follow named`
   182  
   183  def f(x=1, y): pass ### `required parameter may not follow optional`
   184  ---
   185  # No parameters may follow **kwargs
   186  
   187  def f(**kwargs, x): ### `parameter may not follow \*\*kwargs`
   188    pass
   189  
   190  def g(**kwargs, *args): ### `\*args may not follow \*\*kwargs`
   191    pass
   192  
   193  def h(**kwargs1, **kwargs2): ### `multiple \*\*kwargs not allowed`
   194    pass
   195  
   196  ---
   197  # Only **kwargs may follow *args
   198  
   199  def f(*args, x): ### `parameter may not follow \*args`
   200    pass
   201  
   202  def g(*args1, *args2): ### `multiple \*args not allowed`
   203    pass
   204  
   205  def h(*args, **kwargs): # ok
   206    pass
   207  
   208  ---
   209  # No arguments may follow **kwargs
   210  def f(*args, **kwargs):
   211    pass
   212  
   213  f(**{}, 1) ### `argument may not follow \*\*kwargs`
   214  f(**{}, x=1) ### `argument may not follow \*\*kwargs`
   215  f(**{}, *[]) ### `\*args may not follow \*\*kwargs`
   216  f(**{}, **{}) ### `multiple \*\*kwargs not allowed`
   217  
   218  ---
   219  # Only keyword arguments may follow *args
   220  def f(*args, **kwargs):
   221    pass
   222  
   223  f(*[], 1) ### `argument may not follow \*args`
   224  f(*[], a=1) # ok
   225  f(*[], *[]) ### `multiple \*args not allowed`
   226  f(*[], **{}) # ok
   227  
   228  ---
   229  # Parameter names must be unique.
   230  
   231  def f(a, b, a): pass ### "duplicate parameter: a"
   232  def g(args, b, *args): pass ### "duplicate parameter: args"
   233  def h(kwargs, a, **kwargs): pass ### "duplicate parameter: kwargs"
   234  def i(*x, **x): pass ### "duplicate parameter: x"
   235  
   236  ---
   237  # No floating point
   238  a = float("3.141") ### `dialect does not support floating point`
   239  b = 1 / 2          ### `dialect does not support floating point \(use //\)`
   240  c = 3.141          ### `dialect does not support floating point`
   241  ---
   242  # Floating point support (option:float)
   243  a = float("3.141")
   244  b = 1 / 2
   245  c = 3.141