summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2018-03-18 07:56:52 (GMT)
committerGitHub <noreply@github.com>2018-03-18 07:56:52 (GMT)
commitfe2bbb1869b42222a3f331a3dfb8b304a19a5819 (patch)
tree0f9e51eb7b9dbfab1d92a1538cef297081a46b55 /Lib
parent134cb01cda50f02725575808130b05d2d776693f (diff)
downloadcpython-fe2bbb1869b42222a3f331a3dfb8b304a19a5819.zip
cpython-fe2bbb1869b42222a3f331a3dfb8b304a19a5819.tar.gz
cpython-fe2bbb1869b42222a3f331a3dfb8b304a19a5819.tar.bz2
bpo-32489: Allow 'continue' in 'finally' clause. (GH-5822)
Diffstat (limited to 'Lib')
-rw-r--r--Lib/test/test_compile.py4
-rw-r--r--Lib/test/test_exceptions.py9
-rw-r--r--Lib/test/test_grammar.py53
-rw-r--r--Lib/test/test_syntax.py68
4 files changed, 79 insertions, 55 deletions
diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py
index acebdbd..6b45a24 100644
--- a/Lib/test/test_compile.py
+++ b/Lib/test/test_compile.py
@@ -856,7 +856,7 @@ class TestStackSizeStability(unittest.TestCase):
"""
self.check_stack_size(snippet)
- def test_for_break_inside_finally_block(self):
+ def test_for_break_continue_inside_finally_block(self):
snippet = """
for x in y:
try:
@@ -864,6 +864,8 @@ class TestStackSizeStability(unittest.TestCase):
finally:
if z:
break
+ elif u:
+ continue
else:
a
else:
diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py
index 9d10df5..2a9ec70 100644
--- a/Lib/test/test_exceptions.py
+++ b/Lib/test/test_exceptions.py
@@ -138,15 +138,6 @@ class ExceptionTests(unittest.TestCase):
else:
self.fail("failed to get expected SyntaxError")
- s = '''while 1:
- try:
- pass
- finally:
- continue'''
-
- if not sys.platform.startswith('java'):
- ckmsg(s, "'continue' not supported inside 'finally' clause")
-
s = '''if 1:
try:
continue
diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py
index d89bfdc..ee41362 100644
--- a/Lib/test/test_grammar.py
+++ b/Lib/test/test_grammar.py
@@ -859,6 +859,59 @@ class GrammarTests(unittest.TestCase):
break
self.assertEqual(count, 0)
+ def test_continue_in_finally(self):
+ count = 0
+ while count < 2:
+ count += 1
+ try:
+ pass
+ finally:
+ continue
+ break
+ self.assertEqual(count, 2)
+
+ count = 0
+ while count < 2:
+ count += 1
+ try:
+ break
+ finally:
+ continue
+ self.assertEqual(count, 2)
+
+ count = 0
+ while count < 2:
+ count += 1
+ try:
+ 1/0
+ finally:
+ continue
+ break
+ self.assertEqual(count, 2)
+
+ for count in [0, 1]:
+ try:
+ pass
+ finally:
+ continue
+ break
+ self.assertEqual(count, 1)
+
+ for count in [0, 1]:
+ try:
+ break
+ finally:
+ continue
+ self.assertEqual(count, 1)
+
+ for count in [0, 1]:
+ try:
+ 1/0
+ finally:
+ continue
+ break
+ self.assertEqual(count, 1)
+
def test_return_in_finally(self):
def g1():
try:
diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py
index 2b96a94..fa1e7aa 100644
--- a/Lib/test/test_syntax.py
+++ b/Lib/test/test_syntax.py
@@ -298,7 +298,7 @@ continue in for loop under finally should be ok.
>>> test()
9
-Start simple, a continue in a finally should not be allowed.
+continue in a finally should be ok.
>>> def test():
... for abc in range(10):
@@ -306,11 +306,9 @@ Start simple, a continue in a finally should not be allowed.
... pass
... finally:
... continue
- Traceback (most recent call last):
- ...
- SyntaxError: 'continue' not supported inside 'finally' clause
-
-This is essentially a continue in a finally which should not be allowed.
+ ... print(abc)
+ >>> test()
+ 9
>>> def test():
... for abc in range(10):
@@ -321,9 +319,24 @@ This is essentially a continue in a finally which should not be allowed.
... continue
... except:
... pass
- Traceback (most recent call last):
- ...
- SyntaxError: 'continue' not supported inside 'finally' clause
+ ... print(abc)
+ >>> test()
+ 9
+
+ >>> def test():
+ ... for abc in range(10):
+ ... try:
+ ... pass
+ ... finally:
+ ... try:
+ ... pass
+ ... except:
+ ... continue
+ ... print(abc)
+ >>> test()
+ 9
+
+A continue outside loop should not be allowed.
>>> def foo():
... try:
@@ -332,42 +345,7 @@ This is essentially a continue in a finally which should not be allowed.
... continue
Traceback (most recent call last):
...
- SyntaxError: 'continue' not supported inside 'finally' clause
-
- >>> def foo():
- ... for a in ():
- ... try:
- ... pass
- ... finally:
- ... continue
- Traceback (most recent call last):
- ...
- SyntaxError: 'continue' not supported inside 'finally' clause
-
- >>> def foo():
- ... for a in ():
- ... try:
- ... pass
- ... finally:
- ... try:
- ... continue
- ... finally:
- ... pass
- Traceback (most recent call last):
- ...
- SyntaxError: 'continue' not supported inside 'finally' clause
-
- >>> def foo():
- ... for a in ():
- ... try: pass
- ... finally:
- ... try:
- ... pass
- ... except:
- ... continue
- Traceback (most recent call last):
- ...
- SyntaxError: 'continue' not supported inside 'finally' clause
+ SyntaxError: 'continue' not properly in loop
There is one test for a break that is not in a loop. The compiler
uses a single data structure to keep track of try-finally and loops,