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