Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
fe2bbb18
Commit
fe2bbb18
authored
Mar 18, 2018
by
Serhiy Storchaka
Committed by
GitHub
Mar 18, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bpo-32489: Allow 'continue' in 'finally' clause. (GH-5822)
parent
134cb01c
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
97 additions
and
70 deletions
+97
-70
Doc/library/dis.rst
Doc/library/dis.rst
+2
-2
Doc/reference/compound_stmts.rst
Doc/reference/compound_stmts.rst
+7
-6
Doc/reference/simple_stmts.rst
Doc/reference/simple_stmts.rst
+2
-3
Doc/whatsnew/3.8.rst
Doc/whatsnew/3.8.rst
+5
-0
Lib/test/test_compile.py
Lib/test/test_compile.py
+3
-1
Lib/test/test_exceptions.py
Lib/test/test_exceptions.py
+0
-9
Lib/test/test_grammar.py
Lib/test/test_grammar.py
+53
-0
Lib/test/test_syntax.py
Lib/test/test_syntax.py
+23
-45
Misc/NEWS.d/next/Core and Builtins/2018-01-03-23-12-43.bpo-32489.SDEPHB.rst
...ore and Builtins/2018-01-03-23-12-43.bpo-32489.SDEPHB.rst
+2
-0
Python/compile.c
Python/compile.c
+0
-4
No files found.
Doc/library/dis.rst
View file @
fe2bbb18
...
@@ -698,8 +698,8 @@ iterations of the loop.
...
@@ -698,8 +698,8 @@ iterations of the loop.
removed from the block stack.
removed from the block stack.
It is similar to :opcode:`END_FINALLY`, but doesn't change the bytecode
It is similar to :opcode:`END_FINALLY`, but doesn't change the bytecode
counter nor raise an exception. Used for implementing :keyword:`break`
counter nor raise an exception. Used for implementing :keyword:`break`
,
and :keyword:`return` in the :keyword:`finally` block.
:keyword:`continue`
and :keyword:`return` in the :keyword:`finally` block.
.. versionadded:: 3.8
.. versionadded:: 3.8
...
...
Doc/reference/compound_stmts.rst
View file @
fe2bbb18
...
@@ -321,8 +321,8 @@ not handled, the exception is temporarily saved. The :keyword:`finally` clause
...
@@ -321,8 +321,8 @@ not handled, the exception is temporarily saved. The :keyword:`finally` clause
is executed. If there is a saved exception it is re-raised at the end of the
is executed. If there is a saved exception it is re-raised at the end of the
:keyword:`finally` clause. If the :keyword:`finally` clause raises another
:keyword:`finally` clause. If the :keyword:`finally` clause raises another
exception, the saved exception is set as the context of the new exception.
exception, the saved exception is set as the context of the new exception.
If the :keyword:`finally` clause executes a :keyword:`return`
or
:keyword:`break`
If the :keyword:`finally` clause executes a :keyword:`return`
,
:keyword:`break`
statement, the saved exception is discarded::
or :keyword:`continue`
statement, the saved exception is discarded::
>>> def f():
>>> def f():
... try:
... try:
...
@@ -343,10 +343,7 @@ the :keyword:`finally` clause.
...
@@ -343,10 +343,7 @@ the :keyword:`finally` clause.
When a :keyword:`return`, :keyword:`break` or :keyword:`continue` statement is
When a :keyword:`return`, :keyword:`break` or :keyword:`continue` statement is
executed in the :keyword:`try` suite of a :keyword:`try`...\ :keyword:`finally`
executed in the :keyword:`try` suite of a :keyword:`try`...\ :keyword:`finally`
statement, the :keyword:`finally` clause is also executed 'on the way out.' A
statement, the :keyword:`finally` clause is also executed 'on the way out.'
:keyword:`continue` statement is illegal in the :keyword:`finally` clause. (The
reason is a problem with the current implementation --- this restriction may be
lifted in the future).
The return value of a function is determined by the last :keyword:`return`
The return value of a function is determined by the last :keyword:`return`
statement executed. Since the :keyword:`finally` clause always executes, a
statement executed. Since the :keyword:`finally` clause always executes, a
...
@@ -366,6 +363,10 @@ Additional information on exceptions can be found in section :ref:`exceptions`,
...
@@ -366,6 +363,10 @@ Additional information on exceptions can be found in section :ref:`exceptions`,
and information on using the :keyword:`raise` statement to generate exceptions
and information on using the :keyword:`raise` statement to generate exceptions
may be found in section :ref:`raise`.
may be found in section :ref:`raise`.
.. versionchanged:: 3.8
Prior to Python 3.8, a :keyword:`continue` statement was illegal in the
:keyword:`finally` clause due to a problem with the implementation.
.. _with:
.. _with:
.. _as:
.. _as:
...
...
Doc/reference/simple_stmts.rst
View file @
fe2bbb18
...
@@ -686,9 +686,8 @@ The :keyword:`continue` statement
...
@@ -686,9 +686,8 @@ The :keyword:`continue` statement
continue_stmt
:
"continue"
continue_stmt
:
"continue"
:
keyword
:`
continue
`
may
only
occur
syntactically
nested
in
a
:
keyword
:`
for
`
or
:
keyword
:`
continue
`
may
only
occur
syntactically
nested
in
a
:
keyword
:`
for
`
or
:
keyword
:`
while
`
loop
,
but
not
nested
in
a
function
or
class
definition
or
:
keyword
:`
while
`
loop
,
but
not
nested
in
a
function
or
class
definition
within
:
keyword
:`
finally
`
clause
within
that
loop
.
It
continues
with
the
next
that
loop
.
It
continues
with
the
next
cycle
of
the
nearest
enclosing
loop
.
cycle
of
the
nearest
enclosing
loop
.
When
:
keyword
:`
continue
`
passes
control
out
of
a
:
keyword
:`
try
`
statement
with
a
When
:
keyword
:`
continue
`
passes
control
out
of
a
:
keyword
:`
try
`
statement
with
a
:
keyword
:`
finally
`
clause
,
that
:
keyword
:`
finally
`
clause
is
executed
before
:
keyword
:`
finally
`
clause
,
that
:
keyword
:`
finally
`
clause
is
executed
before
...
...
Doc/whatsnew/3.8.rst
View file @
fe2bbb18
...
@@ -72,6 +72,11 @@ New Features
...
@@ -72,6 +72,11 @@ New Features
Other Language Changes
Other Language Changes
======================
======================
* A :keyword:`continue` statement was illegal in the :keyword:`finally` clause
due to a problem with the implementation. In Python 3.8 this restriction
was lifted.
(Contributed by Serhiy Storchaka in :issue:`32489`.)
* Added support of ``\N{name}`` escapes in :mod:`regular expressions <re>`.
* Added support of ``\N{name}`` escapes in :mod:`regular expressions <re>`.
(Contributed by Jonathan Eunice and Serhiy Storchaka in :issue:`30688`.)
(Contributed by Jonathan Eunice and Serhiy Storchaka in :issue:`30688`.)
...
...
Lib/test/test_compile.py
View file @
fe2bbb18
...
@@ -856,7 +856,7 @@ class TestStackSizeStability(unittest.TestCase):
...
@@ -856,7 +856,7 @@ class TestStackSizeStability(unittest.TestCase):
"""
"""
self
.
check_stack_size
(
snippet
)
self
.
check_stack_size
(
snippet
)
def
test_for_break_inside_finally_block
(
self
):
def
test_for_break_
continue_
inside_finally_block
(
self
):
snippet
=
"""
snippet
=
"""
for x in y:
for x in y:
try:
try:
...
@@ -864,6 +864,8 @@ class TestStackSizeStability(unittest.TestCase):
...
@@ -864,6 +864,8 @@ class TestStackSizeStability(unittest.TestCase):
finally:
finally:
if z:
if z:
break
break
elif u:
continue
else:
else:
a
a
else:
else:
...
...
Lib/test/test_exceptions.py
View file @
fe2bbb18
...
@@ -138,15 +138,6 @@ class ExceptionTests(unittest.TestCase):
...
@@ -138,15 +138,6 @@ class ExceptionTests(unittest.TestCase):
else
:
else
:
self
.
fail
(
"failed to get expected SyntaxError"
)
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:
s
=
'''if 1:
try:
try:
continue
continue
...
...
Lib/test/test_grammar.py
View file @
fe2bbb18
...
@@ -859,6 +859,59 @@ class GrammarTests(unittest.TestCase):
...
@@ -859,6 +859,59 @@ class GrammarTests(unittest.TestCase):
break
break
self
.
assertEqual
(
count
,
0
)
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
test_return_in_finally
(
self
):
def
g1
():
def
g1
():
try
:
try
:
...
...
Lib/test/test_syntax.py
View file @
fe2bbb18
...
@@ -298,7 +298,7 @@ continue in for loop under finally should be ok.
...
@@ -298,7 +298,7 @@ continue in for loop under finally should be ok.
>>> test()
>>> test()
9
9
Start simple, a continue in a finally should not be allowed
.
continue in a finally should be ok
.
>>> def test():
>>> def test():
... for abc in range(10):
... for abc in range(10):
...
@@ -306,11 +306,9 @@ Start simple, a continue in a finally should not be allowed.
...
@@ -306,11 +306,9 @@ Start simple, a continue in a finally should not be allowed.
... pass
... pass
... finally:
... finally:
... continue
... continue
Traceback (most recent call last):
... print(abc)
...
>>> test()
SyntaxError: 'continue' not supported inside 'finally' clause
9
This is essentially a continue in a finally which should not be allowed.
>>> def test():
>>> def test():
... for abc in range(10):
... for abc in range(10):
...
@@ -321,53 +319,33 @@ This is essentially a continue in a finally which should not be allowed.
...
@@ -321,53 +319,33 @@ This is essentially a continue in a finally which should not be allowed.
... continue
... continue
... except:
... except:
... pass
... pass
Traceback (most recent call last):
... print(abc)
...
>>> test()
SyntaxError: 'continue' not supported inside 'finally' clause
9
>>> def foo():
>>> def test():
... for abc in range(10):
... try:
... try:
... pass
... pass
... finally:
... finally:
... continue
Traceback (most recent call last):
...
SyntaxError: 'continue' not supported inside 'finally' clause
>>> def foo():
... for a in ():
... try:
... try:
... pass
... pass
...
finally
:
...
except
:
... continue
... continue
Traceback (most recent call last):
... print(abc)
...
>>> test()
SyntaxError: 'continue' not supported inside 'finally' clause
9
>>> def foo():
A continue outside loop should not be allowed.
... for a in ():
... try:
... pass
... finally:
... try:
... continue
... finally:
... pass
Traceback (most recent call last):
...
SyntaxError: 'continue' not supported inside 'finally' clause
>>> def foo():
>>> def foo():
... for a in ():
... try: pass
... finally:
... try:
... try:
... pass
... pass
...
except
:
...
finally
:
... continue
... continue
Traceback (most recent call last):
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
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,
uses a single data structure to keep track of try-finally and loops,
...
...
Misc/NEWS.d/next/Core and Builtins/2018-01-03-23-12-43.bpo-32489.SDEPHB.rst
0 → 100644
View file @
fe2bbb18
A :keyword:`continue` statement is now allowed in the :keyword:`finally`
clause.
Python/compile.c
View file @
fe2bbb18
...
@@ -2625,10 +2625,6 @@ compiler_continue(struct compiler *c)
...
@@ -2625,10 +2625,6 @@ compiler_continue(struct compiler *c)
ADDOP_JABS
(
c
,
JUMP_ABSOLUTE
,
info
->
fb_block
);
ADDOP_JABS
(
c
,
JUMP_ABSOLUTE
,
info
->
fb_block
);
return
1
;
return
1
;
}
}
if
(
info
->
fb_type
==
FINALLY_END
)
{
return
compiler_error
(
c
,
"'continue' not supported inside 'finally' clause"
);
}
if
(
!
compiler_unwind_fblock
(
c
,
info
,
0
))
if
(
!
compiler_unwind_fblock
(
c
,
info
,
0
))
return
0
;
return
0
;
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment