aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/test/test_syntax.py
diff options
context:
space:
mode:
authorCrowthebird <78076854+thatbirdguythatuknownot@users.noreply.github.com>2023-11-20 21:27:53 +0800
committerGitHub <noreply@github.com>2023-11-20 13:27:53 +0000
commit1c8f912ebdfdb146cd7dd2d7a3a67d2c5045ddb0 (patch)
treed2553d0e973e0d59f0bc20c90aba252c5efd6c40 /Lib/test/test_syntax.py
parent56e59a49ae4d9f518c5cc918aefe7eeee11736b4 (diff)
downloadcpython-1c8f912ebdfdb146cd7dd2d7a3a67d2c5045ddb0.tar.gz
cpython-1c8f912ebdfdb146cd7dd2d7a3a67d2c5045ddb0.zip
bpo-45759: Better error messages for non-matching 'elif'/'else' statements (#29513)
Diffstat (limited to 'Lib/test/test_syntax.py')
-rw-r--r--Lib/test/test_syntax.py61
1 files changed, 59 insertions, 2 deletions
diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py
index 7ebf9ca1707..f6fa6495508 100644
--- a/Lib/test/test_syntax.py
+++ b/Lib/test/test_syntax.py
@@ -1752,6 +1752,28 @@ Corner-cases that used to crash:
Traceback (most recent call last):
SyntaxError: positional patterns follow keyword patterns
+Non-matching 'elif'/'else' statements:
+
+ >>> if a == b:
+ ... ...
+ ... elif a == c:
+ Traceback (most recent call last):
+ SyntaxError: 'elif' must match an if-statement here
+
+ >>> if x == y:
+ ... ...
+ ... else:
+ Traceback (most recent call last):
+ SyntaxError: 'else' must match a valid statement here
+
+ >>> elif m == n:
+ Traceback (most recent call last):
+ SyntaxError: 'elif' must match an if-statement here
+
+ >>> else:
+ Traceback (most recent call last):
+ SyntaxError: 'else' must match a valid statement here
+
Uses of the star operator which should fail:
A[:*b]
@@ -2006,8 +2028,8 @@ class SyntaxTestCase(unittest.TestCase):
lineno=None, offset=None, end_lineno=None, end_offset=None):
"""Check that compiling code raises SyntaxError with errtext.
- errtest is a regular expression that must be present in the
- test of the exception raised. If subclass is specified it
+ errtext is a regular expression that must be present in the
+ test of the exception raised. If subclass is specified, it
is the expected subclass of SyntaxError (e.g. IndentationError).
"""
try:
@@ -2031,6 +2053,22 @@ class SyntaxTestCase(unittest.TestCase):
else:
self.fail("compile() did not raise SyntaxError")
+ def _check_noerror(self, code,
+ errtext="compile() raised unexpected SyntaxError",
+ filename="<testcase>", mode="exec", subclass=None):
+ """Check that compiling code does not raise a SyntaxError.
+
+ errtext is the message passed to self.fail if there is
+ a SyntaxError. If the subclass parameter is specified,
+ it is the subclass of SyntaxError (e.g. IndentationError)
+ that the raised error is checked against.
+ """
+ try:
+ compile(code, filename, mode)
+ except SyntaxError as err:
+ if (not subclass) or isinstance(err, subclass):
+ self.fail(errtext)
+
def test_expression_with_assignment(self):
self._check_error(
"print(end1 + end2 = ' ')",
@@ -2372,6 +2410,25 @@ while 1:
"""
self._check_error(source, "too many statically nested blocks")
+ def test_syntax_error_non_matching_elif_else_statements(self):
+ # Check bpo-45759: 'elif' statements that doesn't match an
+ # if-statement or 'else' statements that doesn't match any
+ # valid else-able statement (e.g. 'while')
+ self._check_error(
+ "elif m == n:\n ...",
+ "'elif' must match an if-statement here")
+ self._check_error(
+ "else:\n ...",
+ "'else' must match a valid statement here")
+ self._check_noerror("if a == b:\n ...\nelif a == c:\n ...")
+ self._check_noerror("if x == y:\n ...\nelse:\n ...")
+ self._check_error(
+ "else = 123",
+ "invalid syntax")
+ self._check_error(
+ "elif 55 = 123",
+ "cannot assign to literal here")
+
@support.cpython_only
def test_error_on_parser_stack_overflow(self):
source = "-" * 100000 + "4"