1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
|
# Tests of parse errors.
# This is a "chunked" file; each "---" line demarcates a new parser input.
#
# TODO(adonovan): lots more tests.
x = 1 + ### "got newline, want primary expression"
2
---
_ = *x ### `got '\*', want primary`
---
# trailing comma is ok
def f(a, ): pass
def f(*args, ): pass
def f(**kwargs, ): pass
---
# Parameters are validated later.
def f(**kwargs, *args, *, b=1, a, **kwargs, *args, *, b=1, a):
pass
---
def f(a, *-b, c): # ### `got '-', want ','`
pass
---
def f(**kwargs, *args, b=1, a, **kwargs, *args, b=1, a):
pass
---
def pass(): ### "not an identifier"
pass
---
def f : ### `got ':', want '\('`
---
# trailing comma is ok
f(a, )
f(*args, )
f(**kwargs, )
---
f(a=1, *, b=2) ### `got ',', want primary`
---
_ = {x:y for y in z} # ok
_ = {x for y in z} ### `got for, want ':'`
---
def f():
pass
pass ### `unindent does not match any outer indentation level`
---
def f(): pass
---
# Blank line after pass => outdent.
def f():
pass
---
# No blank line after pass; EOF acts like a newline.
def f():
pass
---
# This is a well known parsing ambiguity in Python.
# Python 2.7 accepts it but Python3 and Starlark reject it.
_ = [x for x in lambda: True, lambda: False if x()] ### "got lambda, want primary"
_ = [x for x in (lambda: True, lambda: False) if x()] # ok in all dialects
---
# Starlark, following Python 3, allows an unparenthesized
# tuple after 'in' only in a for statement but not in a comprehension.
# (Python 2.7 allows both.)
for x in 1, 2, 3:
print(x)
_ = [x for x in 1, 2, 3] ### `got ',', want ']', for, or if`
---
# Unparenthesized tuple is not allowed as operand of 'if' in comprehension.
_ = [a for b in c if 1, 2] ### `got ',', want ']', for, or if`
---
# Lambda is ok though.
_ = [a for b in c if lambda: d] # ok
# But the body of such a lambda may not be a conditional:
_ = [a for b in c if (lambda: d if e else f)] # ok
_ = [a for b in c if lambda: d if e else f] ### "got else, want ']'"
---
# A lambda is not allowed as the operand of a 'for' clause.
_ = [a for b in lambda: c] ### `got lambda, want primary`
---
# Comparison operations are not associative.
_ = (0 == 1) == 2 # ok
_ = 0 == (1 == 2) # ok
_ = 0 == 1 == 2 ### "== does not associate with =="
---
_ = (0 <= i) < n # ok
_ = 0 <= (i < n) # ok
_ = 0 <= i < n ### "<= does not associate with <"
---
_ = (a in b) not in c # ok
_ = a in (b not in c) # ok
_ = a in b not in c ### "in does not associate with not in"
---
# shift/reduce ambiguity is reduced
_ = [x for x in a if b else c] ### `got else, want ']', for, or if`
---
[a for b in c else d] ### `got else, want ']', for, or if`
---
_ = a + b not c ### "got identifier, want in"
---
f(1+2 = 3) ### "keyword argument must have form name=expr"
---
print(1, 2, 3
### `got end of file, want '\)'`
---
_ = a if b ### "conditional expression without else clause"
---
load("") ### "load statement must import at least 1 symbol"
---
load("", 1) ### `load operand must be "name" or localname="name" \(got int literal\)`
---
load("a", "x") # ok
---
load(1, 2) ### "first operand of load statement must be a string literal"
---
load("a", x) ### `load operand must be "x" or x="originalname"`
---
load("a", x2=x) ### `original name of loaded symbol must be quoted: x2="originalname"`
---
# All of these parse.
load("a", "x")
load("a", "x", y2="y")
load("a", x2="x", "y") # => positional-before-named arg check happens later (!)
---
# 'load' is not an identifier
load = 1 ### `got '=', want '\('`
---
# 'load' is not an identifier
f(load()) ### `got load, want primary`
---
# 'load' is not an identifier
def load(): ### `not an identifier`
pass
---
# 'load' is not an identifier
def f(load): ### `not an identifier`
pass
---
# A load statement allows a trailing comma.
load("module", "x",)
---
x = 1 + ### "got newline, want primary expression"
2
---
def f():
pass
# this used to cause a spurious indentation error
---
print 1 2 ### `got int literal, want newline`
---
# newlines are not allowed in raw string literals
raw = r'a ### `unexpected newline in string`
b'
---
# The parser permits an unparenthesized tuple expression for the first index.
x[1, 2:] # ok
---
# But not if it has a trailing comma.
x[1, 2,:] ### `got ':', want primary`
---
# Trailing tuple commas are permitted only within parens; see b/28867036.
(a, b,) = 1, 2 # ok
c, d = 1, 2 # ok
---
a, b, = 1, 2 ### `unparenthesized tuple with trailing comma`
---
a, b = 1, 2, ### `unparenthesized tuple with trailing comma`
---
# See github.com/google/starlark-go/issues/48
a = max(range(10))) ### `unexpected '\)'`
---
# github.com/google/starlark-go/issues/85
s = "\x-0" ### `invalid escape sequence`
|