1752
1752
Traceback (most recent call last):
1753
1753
SyntaxError: positional patterns follow keyword patterns
1754
1754
1755
+ Non-matching 'elif'/'else' statements:
1756
+
1757
+ >>> if a == b:
1758
+ ... ...
1759
+ ... elif a == c:
1760
+ Traceback (most recent call last):
1761
+ SyntaxError: 'elif' must match an if-statement here
1762
+
1763
+ >>> if x == y:
1764
+ ... ...
1765
+ ... else:
1766
+ Traceback (most recent call last):
1767
+ SyntaxError: 'else' must match a valid statement here
1768
+
1769
+ >>> elif m == n:
1770
+ Traceback (most recent call last):
1771
+ SyntaxError: 'elif' must match an if-statement here
1772
+
1773
+ >>> else:
1774
+ Traceback (most recent call last):
1775
+ SyntaxError: 'else' must match a valid statement here
1776
+
1755
1777
Uses of the star operator which should fail:
1756
1778
1757
1779
A[:*b]
@@ -2006,8 +2028,8 @@ def _check_error(self, code, errtext,
2006
2028
lineno = None , offset = None , end_lineno = None , end_offset = None ):
2007
2029
"""Check that compiling code raises SyntaxError with errtext.
2008
2030
2009
- errtest is a regular expression that must be present in the
2010
- test of the exception raised. If subclass is specified it
2031
+ errtext is a regular expression that must be present in the
2032
+ test of the exception raised. If subclass is specified, it
2011
2033
is the expected subclass of SyntaxError (e.g. IndentationError).
2012
2034
"""
2013
2035
try :
@@ -2031,6 +2053,22 @@ def _check_error(self, code, errtext,
2031
2053
else :
2032
2054
self .fail ("compile() did not raise SyntaxError" )
2033
2055
2056
+ def _check_noerror (self , code ,
2057
+ errtext = "compile() raised unexpected SyntaxError" ,
2058
+ filename = "<testcase>" , mode = "exec" , subclass = None ):
2059
+ """Check that compiling code does not raise a SyntaxError.
2060
+
2061
+ errtext is the message passed to self.fail if there is
2062
+ a SyntaxError. If the subclass parameter is specified,
2063
+ it is the subclass of SyntaxError (e.g. IndentationError)
2064
+ that the raised error is checked against.
2065
+ """
2066
+ try :
2067
+ compile (code , filename , mode )
2068
+ except SyntaxError as err :
2069
+ if (not subclass ) or isinstance (err , subclass ):
2070
+ self .fail (errtext )
2071
+
2034
2072
def test_expression_with_assignment (self ):
2035
2073
self ._check_error (
2036
2074
"print(end1 + end2 = ' ')" ,
@@ -2372,6 +2410,25 @@ def test_syntax_error_on_deeply_nested_blocks(self):
2372
2410
"""
2373
2411
self ._check_error (source , "too many statically nested blocks" )
2374
2412
2413
+ def test_syntax_error_non_matching_elif_else_statements (self ):
2414
+ # Check bpo-45759: 'elif' statements that doesn't match an
2415
+ # if-statement or 'else' statements that doesn't match any
2416
+ # valid else-able statement (e.g. 'while')
2417
+ self ._check_error (
2418
+ "elif m == n:\n ..." ,
2419
+ "'elif' must match an if-statement here" )
2420
+ self ._check_error (
2421
+ "else:\n ..." ,
2422
+ "'else' must match a valid statement here" )
2423
+ self ._check_noerror ("if a == b:\n ...\n elif a == c:\n ..." )
2424
+ self ._check_noerror ("if x == y:\n ...\n else:\n ..." )
2425
+ self ._check_error (
2426
+ "else = 123" ,
2427
+ "invalid syntax" )
2428
+ self ._check_error (
2429
+ "elif 55 = 123" ,
2430
+ "cannot assign to literal here" )
2431
+
2375
2432
@support .cpython_only
2376
2433
def test_error_on_parser_stack_overflow (self ):
2377
2434
source = "-" * 100000 + "4"
0 commit comments