bpo-42997: Improve error message for missing : before suites (GH-24292)
* Add to the peg generator a new directive ('&&') that allows to expect
a token and hard fail the parsing if the token is not found. This
allows to quickly emmit syntax errors for missing tokens.
* Use the new grammar element to hard-fail if the ':' is missing before
suites.
diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py
index 604474f..6068dd9 100644
--- a/Lib/test/test_syntax.py
+++ b/Lib/test/test_syntax.py
@@ -229,7 +229,7 @@
>>> with a as b
Traceback (most recent call last):
-SyntaxError: invalid syntax
+SyntaxError: expected ':'
>>> p = p =
Traceback (most recent call last):
@@ -331,7 +331,7 @@
>>> class C(x for x in L):
... pass
Traceback (most recent call last):
-SyntaxError: invalid syntax
+SyntaxError: expected ':'
>>> def g(*args, **kwargs):
... print(args, sorted(kwargs.items()))
@@ -708,6 +708,107 @@
...
SyntaxError: cannot assign to function call
+ Missing ':' before suites:
+
+ >>> def f()
+ ... pass
+ Traceback (most recent call last):
+ SyntaxError: expected ':'
+
+ >>> class A
+ ... pass
+ Traceback (most recent call last):
+ SyntaxError: expected ':'
+
+ >>> if 1
+ ... pass
+ ... elif 1:
+ ... pass
+ ... else:
+ ... x() = 1
+ Traceback (most recent call last):
+ SyntaxError: expected ':'
+
+ >>> if 1:
+ ... pass
+ ... elif 1
+ ... pass
+ ... else:
+ ... x() = 1
+ Traceback (most recent call last):
+ SyntaxError: expected ':'
+
+ >>> if 1:
+ ... pass
+ ... elif 1:
+ ... pass
+ ... else
+ ... x() = 1
+ Traceback (most recent call last):
+ SyntaxError: expected ':'
+
+ >>> for x in range(10)
+ ... pass
+ Traceback (most recent call last):
+ SyntaxError: expected ':'
+
+ >>> while True
+ ... pass
+ Traceback (most recent call last):
+ SyntaxError: expected ':'
+
+ >>> with blech as something
+ ... pass
+ Traceback (most recent call last):
+ SyntaxError: expected ':'
+
+ >>> with blech
+ ... pass
+ Traceback (most recent call last):
+ SyntaxError: expected ':'
+
+ >>> with blech, block as something
+ ... pass
+ Traceback (most recent call last):
+ SyntaxError: expected ':'
+
+ >>> with blech, block as something, bluch
+ ... pass
+ Traceback (most recent call last):
+ SyntaxError: expected ':'
+
+ >>> with (blech as something)
+ ... pass
+ Traceback (most recent call last):
+ SyntaxError: expected ':'
+
+ >>> with (blech)
+ ... pass
+ Traceback (most recent call last):
+ SyntaxError: expected ':'
+
+ >>> with (blech, block as something)
+ ... pass
+ Traceback (most recent call last):
+ SyntaxError: expected ':'
+
+ >>> with (blech, block as something, bluch)
+ ... pass
+ Traceback (most recent call last):
+ SyntaxError: expected ':'
+
+ >>> try
+ ... pass
+ Traceback (most recent call last):
+ SyntaxError: expected ':'
+
+ >>> try:
+ ... pass
+ ... except
+ ... pass
+ Traceback (most recent call last):
+ SyntaxError: expected ':'
+
Make sure that the old "raise X, Y[, Z]" form is gone:
>>> raise X, Y
Traceback (most recent call last):
@@ -992,7 +1093,7 @@ def func2():
finally:
pass
"""
- self._check_error(code, "invalid syntax")
+ self._check_error(code, "expected ':'")
def test_invalid_line_continuation_left_recursive(self):
# Check bpo-42218: SyntaxErrors following left-recursive rules