github.com/google/skylark@v0.0.0-20181101142754-a5f7082aabed/testdata/assign.sky (about)

     1  # Tests of Skylark assignment.
     2  
     3  # This is a "chunked" file: each "---" effectively starts a new file.
     4  
     5  # tuple assignment
     6  load("assert.sky", "assert")
     7  
     8  a, b, c = 1, 2, 3
     9  assert.eq(a, 1)
    10  assert.eq(b, 2)
    11  assert.eq(c, 3)
    12  
    13  def f1(): (x,) = 1
    14  assert.fails(f1, "int in sequence assignment")
    15  def f2(): a, b, c = 1, 2
    16  assert.fails(f2, "too few values to unpack")
    17  def f3(): a, b = 1, 2, 3
    18  assert.fails(f3, "too many values to unpack")
    19  def f4(): a, b = (1,)
    20  assert.fails(f4, "too few values to unpack")
    21  def f5(): (a,) = [1, 2, 3]
    22  assert.fails(f5, "too many values to unpack")
    23  
    24  ---
    25  # list assignment
    26  load("assert.sky", "assert")
    27  
    28  [a, b, c] = [1, 2, 3]
    29  assert.eq(a, 1)
    30  assert.eq(b, 2)
    31  assert.eq(c, 3)
    32  
    33  def f1(): [a, b, c,] = 1
    34  assert.fails(f1, "got int in sequence assignment")
    35  def f2(): [a, b, c] = 1, 2
    36  assert.fails(f2, "too few values to unpack")
    37  def f3(): [a, b] = 1, 2, 3
    38  assert.fails(f3, "too many values to unpack")
    39  def f4(): [a, b] = (1,)
    40  assert.fails(f4, "too few values to unpack")
    41  
    42  ---
    43  # list-tuple assignment
    44  load("assert.sky", "assert")
    45  
    46  [a, b, c] = (1, 2, 3)
    47  assert.eq(a, 1)
    48  assert.eq(b, 2)
    49  assert.eq(c, 3)
    50  
    51  (d, e, f) = [1, 2, 3]
    52  assert.eq(d, 1)
    53  assert.eq(e, 2)
    54  assert.eq(f, 3)
    55  
    56  [g, h, (i, j)] = (1, 2, [3, 4])
    57  assert.eq(g, 1)
    58  assert.eq(h, 2)
    59  assert.eq(i, 3)
    60  assert.eq(j, 4)
    61  
    62  (k, l, [m, n]) = [1, 2, (3, 4)]
    63  assert.eq(k, 1)
    64  assert.eq(l, 2)
    65  assert.eq(m, 3)
    66  assert.eq(n, 4)
    67  
    68  ---
    69  # misc assignment
    70  load("assert.sky", "assert")
    71  
    72  def assignment():
    73    a = [1, 2, 3]
    74    a[1] = 5
    75    assert.eq(a, [1, 5, 3])
    76    a[-2] = 2
    77    assert.eq(a, [1, 2, 3])
    78    assert.eq("%d %d" % (5, 7), "5 7")
    79    x={}
    80    x[1] = 2
    81    x[1] += 3
    82    assert.eq(x[1], 5)
    83    def f12(): x[(1, "abc", {})] = 1
    84    assert.fails(f12, "unhashable type: dict")
    85  
    86  assignment()
    87  
    88  ---
    89  # augmented assignment
    90  
    91  load("assert.sky", "assert")
    92  
    93  def f():
    94    x = 1
    95    x += 1
    96    assert.eq(x, 2)
    97    x *= 3
    98    assert.eq(x, 6)
    99  f()
   100  
   101  ---
   102  # effects of evaluating LHS occur only once
   103  
   104  load("assert.sky", "assert")
   105  
   106  count = [0] # count[0] is the number of calls to f
   107  
   108  def f():
   109    count[0] += 1
   110    return count[0]
   111  
   112  x = [1, 2, 3]
   113  x[f()] += 1
   114  
   115  assert.eq(x, [1, 3, 3]) # sole call to f returned 1
   116  assert.eq(count[0], 1) # f was called only once
   117  
   118  ---
   119  # Order of evaluation.
   120  
   121  load("assert.sky", "assert")
   122  
   123  calls = []
   124  
   125  def f(name, result):
   126    calls.append(name)
   127    return result
   128  
   129  # The right side is evaluated before the left in an ordinary assignment.
   130  calls.clear()
   131  f("array", [0])[f("index", 0)] = f("rhs", 0)
   132  assert.eq(calls, ["rhs", "array", "index"])
   133  
   134  calls.clear()
   135  f("lhs1", [0])[0], f("lhs2", [0])[0] = f("rhs1", 0), f("rhs2", 0)
   136  assert.eq(calls, ["rhs1", "rhs2", "lhs1", "lhs2"])
   137  
   138  # Left side is evaluated first (and only once) in an augmented assignment.
   139  calls.clear()
   140  f("array", [0])[f("index", 0)] += f("addend", 1)
   141  assert.eq(calls, ["array", "index", "addend"])
   142  
   143  ---
   144  # global referenced before assignment
   145  
   146  def f():
   147     return g ### "global variable g referenced before assignment"
   148  
   149  f()
   150  
   151  g = 1
   152  
   153  ---
   154  # free variable captured before assignment
   155  
   156  def f():
   157     def g(): ### "local variable outer referenced before assignment"
   158       return outer
   159     outer = 1
   160  
   161  f()
   162  
   163  ---
   164  load("assert.sky", "assert")
   165  
   166  printok = [False]
   167  
   168  # This program should resolve successfully but fail dynamically.
   169  # However, the Java implementation currently reports the dynamic
   170  # error at the x=1 statement (b/33975425).  I think we need to simplify
   171  # the resolver algorithm to what we have implemented.
   172  def use_before_def():
   173    print(x) # dynamic error: local var referenced before assignment
   174    printok[0] = True
   175    x = 1  # makes 'x' local
   176  
   177  assert.fails(use_before_def, 'local variable x referenced before assignment')
   178  assert.true(not printok[0]) # execution of print statement failed
   179  
   180  ---
   181  x = [1]
   182  x.extend([2]) # ok
   183  
   184  def f():
   185     x += [4] ### "local variable x referenced before assignment"
   186  
   187  f()
   188  
   189  ---
   190  
   191  z += 3 ### "global variable z referenced before assignment"
   192  
   193  ---
   194  load("assert.sky", "assert")
   195  
   196  # It's ok to define a global that shadows a built-in...
   197  list = []
   198  assert.eq(type(list), "list")
   199  
   200  # ...but then all uses refer to the global,
   201  # even if they occur before the binding use.
   202  # See github.com/google/skylark/issues/116.
   203  assert.fails(lambda: tuple, "global variable tuple referenced before assignment")
   204  tuple = ()
   205  
   206  ---
   207  # Same as above, but set and float are dialect-specific;
   208  # we shouldn't notice any difference.
   209  load("assert.sky", "assert")
   210  
   211  float = 1.0
   212  assert.eq(type(float), "float")
   213  
   214  set = [1, 2, 3]
   215  assert.eq(type(set), "list")
   216  
   217  # As in Python 2 and Python 3,
   218  # all 'in x' expressions in a comprehension are evaluated
   219  # in the comprehension's lexical block, except the first,
   220  # which is resolved in the outer block.
   221  x = [[1, 2]]
   222  assert.eq([x for x in x for y in x],
   223            [[1, 2], [1, 2]])
   224  
   225  ---
   226  # A comprehension establishes a single new lexical block,
   227  # not one per 'for' clause.
   228  x = [1, 2]
   229  _ = [x for _ in [3] for x in x] ### "local variable x referenced before assignment"
   230  
   231  ---
   232  load("assert.sky", "assert")
   233  
   234  # assign singleton sequence to 1-tuple
   235  (x,) = (1,)
   236  assert.eq(x, 1)
   237  (y,) = [1]
   238  assert.eq(y, 1)
   239  
   240  # assign 1-tuple to variable
   241  z = (1,)
   242  assert.eq(type(z), "tuple")
   243  assert.eq(len(z), 1)
   244  assert.eq(z[0], 1)
   245  
   246  ---
   247  # assignment to/from fields.
   248  load("assert.sky", "assert", "freeze")
   249  
   250  hf = hasfields()
   251  hf.x = 1
   252  assert.eq(hf.x, 1)
   253  hf.x = [1, 2]
   254  hf.x += [3, 4]
   255  assert.eq(hf.x, [1, 2, 3, 4])
   256  freeze(hf)
   257  def setX(hf):
   258    hf.x = 2
   259  def setY(hf):
   260    hf.y = 3
   261  assert.fails(lambda: setX(hf), "cannot set field on a frozen hasfields")
   262  assert.fails(lambda: setY(hf), "cannot set field on a frozen hasfields")
   263  
   264  ---
   265  # destucturing assignment in a for loop.
   266  load("assert.sky", "assert")
   267  
   268  def f():
   269    res = []
   270    for (x, y), z in [(["a", "b"], 3), (["c", "d"], 4)]:
   271      res.append((x, y, z))
   272    return res
   273  assert.eq(f(), [("a", "b", 3), ("c", "d", 4)])
   274  
   275  def g():
   276    a = {}
   277    for i, a[i] in [("one", 1), ("two", 2)]:
   278      pass
   279    return a
   280  assert.eq(g(), {"one": 1, "two": 2})