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
3faa52ec
Commit
3faa52ec
authored
Feb 01, 2001
by
Jeremy Hylton
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Allow 'continue' inside 'try' clause
SF patch 102989 by Thomas Wouters
parent
1bbc0483
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
74 additions
and
45 deletions
+74
-45
Doc/ref/ref7.tex
Doc/ref/ref7.tex
+11
-9
Include/opcode.h
Include/opcode.h
+1
-0
Lib/dis.py
Lib/dis.py
+1
-0
Lib/test/output/test_exceptions
Lib/test/output/test_exceptions
+1
-5
Lib/test/output/test_grammar
Lib/test/output/test_grammar
+2
-0
Lib/test/test_exceptions.py
Lib/test/test_exceptions.py
+2
-19
Lib/test/test_grammar.py
Lib/test/test_grammar.py
+19
-0
Python/ceval.c
Python/ceval.c
+24
-4
Python/compile.c
Python/compile.c
+13
-8
No files found.
Doc/ref/ref7.tex
View file @
3faa52ec
...
...
@@ -260,17 +260,19 @@ The \keyword{try}...\keyword{finally} form specifies a `cleanup' handler. The
\keyword
{
try
}
clause, the exception is temporarily saved, the
\keyword
{
finally
}
clause is executed, and then the saved exception is
re-raised. If the
\keyword
{
finally
}
clause raises another exception or
executes a
\keyword
{
return
}
,
\keyword
{
break
}
or
\keyword
{
continue
}
statement,
the saved exception is lost. The exception information is not
available to the program during execution of the
\keyword
{
finally
}
clause.
executes a
\keyword
{
return
}
or
\keyword
{
break
}
statement, the saved
exception is lost. A
\keyword
{
continue
}
statement is illegal in the
\keyword
{
finally
}
clause. (The reason is a problem with the current
implementation -- thsi restriction may be lifted in the future). The
exception information is not available to the program during execution of
the
\keyword
{
finally
}
clause.
\kwindex
{
finally
}
When a
\keyword
{
return
}
or
\keyword
{
break
}
statement is 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
\keyword
{
continue
}
statement is illegal in the
\keyword
{
try
}
clause. (The
reason is a problem with the current implementation --- this
When a
\keyword
{
return
}
,
\keyword
{
break
}
or
\keyword
{
continue
}
statement is
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
\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).
\stindex
{
return
}
\stindex
{
break
}
...
...
Include/opcode.h
View file @
3faa52ec
...
...
@@ -104,6 +104,7 @@ extern "C" {
#define LOAD_GLOBAL 116
/* Index in name list */
#define CONTINUE_LOOP 119
/* Start of loop (absolute) */
#define SETUP_LOOP 120
/* Target address (absolute) */
#define SETUP_EXCEPT 121
/* "" */
#define SETUP_FINALLY 122
/* "" */
...
...
Lib/dis.py
View file @
3faa52ec
...
...
@@ -259,6 +259,7 @@ jrel_op('FOR_LOOP', 114) # Number of bytes to skip
name_op
(
'LOAD_GLOBAL'
,
116
)
# Index in name list
jabs_op
(
'CONTINUE_LOOP'
,
119
)
# Target address
jrel_op
(
'SETUP_LOOP'
,
120
)
# Distance to target address
jrel_op
(
'SETUP_EXCEPT'
,
121
)
# ""
jrel_op
(
'SETUP_FINALLY'
,
122
)
# ""
...
...
Lib/test/output/test_exceptions
View file @
3faa52ec
...
...
@@ -27,11 +27,7 @@ RuntimeError
(not used any more?)
spam
SyntaxError
'continue' not supported inside 'try' clause
ok
'continue' not supported inside 'try' clause
ok
'continue' not supported inside 'try' clause
'continue' not supported inside 'finally' clause
ok
'continue' not properly in loop
ok
...
...
Lib/test/output/test_grammar
View file @
3faa52ec
...
...
@@ -33,6 +33,8 @@ pass_stmt
flow_stmt
break_stmt
continue_stmt
continue + try/except ok
continue + try/finally ok
return_stmt
raise_stmt
import_stmt
...
...
Lib/test/test_exceptions.py
View file @
3faa52ec
...
...
@@ -104,28 +104,11 @@ def ckmsg(src, msg):
s
=
'''
\
while 1:
try:
continue
except:
pass
'''
ckmsg
(
s
,
"'continue' not supported inside 'try' clause"
)
s
=
'''
\
while 1:
try:
continue
finally:
pass
'''
ckmsg
(
s
,
"'continue' not supported inside 'try' clause"
)
s
=
'''
\
while 1:
try:
if 1:
continue
finally:
pass
continue
'''
ckmsg
(
s
,
"'continue' not supported inside '
tr
y' clause"
)
ckmsg
(
s
,
"'continue' not supported inside '
finall
y' clause"
)
s
=
'''
\
try:
continue
...
...
Lib/test/test_grammar.py
View file @
3faa52ec
...
...
@@ -349,6 +349,25 @@ print 'continue_stmt' # 'continue'
i
=
1
while
i
:
i
=
0
;
continue
msg
=
""
while
not
msg
:
msg
=
"continue + try/except ok"
try
:
continue
msg
=
"continue failed to continue inside try"
except
:
msg
=
"continue inside try called except block"
print
msg
msg
=
""
while
not
msg
:
msg
=
"finally block not called"
try
:
continue
finally
:
msg
=
"continue + try/finally ok"
print
msg
print
'return_stmt'
# 'return' [testlist]
def
g1
():
return
def
g2
():
return
1
...
...
Python/ceval.c
View file @
3faa52ec
...
...
@@ -322,7 +322,8 @@ enum why_code {
WHY_EXCEPTION
,
/* Exception occurred */
WHY_RERAISE
,
/* Exception re-raised by 'finally' */
WHY_RETURN
,
/* 'return' statement */
WHY_BREAK
/* 'break' statement */
WHY_BREAK
,
/* 'break' statement */
WHY_CONTINUE
,
/* 'continue' statement */
};
static
enum
why_code
do_raise
(
PyObject
*
,
PyObject
*
,
PyObject
*
);
...
...
@@ -1357,6 +1358,11 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
case
BREAK_LOOP
:
why
=
WHY_BREAK
;
break
;
case
CONTINUE_LOOP
:
retval
=
PyInt_FromLong
(
oparg
);
why
=
WHY_CONTINUE
;
break
;
case
RAISE_VARARGS
:
u
=
v
=
w
=
NULL
;
...
...
@@ -1419,7 +1425,8 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
v
=
POP
();
if
(
PyInt_Check
(
v
))
{
why
=
(
enum
why_code
)
PyInt_AsLong
(
v
);
if
(
why
==
WHY_RETURN
)
if
(
why
==
WHY_RETURN
||
why
==
CONTINUE_LOOP
)
retval
=
POP
();
}
else
if
(
PyString_Check
(
v
)
||
PyClass_Check
(
v
))
{
...
...
@@ -1834,7 +1841,7 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
case
SETUP_EXCEPT
:
case
SETUP_FINALLY
:
PyFrame_BlockSetup
(
f
,
opcode
,
INSTR_OFFSET
()
+
oparg
,
STACK_LEVEL
());
STACK_LEVEL
());
continue
;
case
SET_LINENO
:
...
...
@@ -2110,6 +2117,18 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
while
(
why
!=
WHY_NOT
&&
f
->
f_iblock
>
0
)
{
PyTryBlock
*
b
=
PyFrame_BlockPop
(
f
);
if
(
b
->
b_type
==
SETUP_LOOP
&&
why
==
WHY_CONTINUE
)
{
/* For a continue inside a try block,
don't pop the block for the loop. */
PyFrame_BlockSetup
(
f
,
b
->
b_type
,
b
->
b_level
,
b
->
b_handler
);
why
=
WHY_NOT
;
JUMPTO
(
PyInt_AS_LONG
(
retval
));
Py_DECREF
(
retval
);
break
;
}
while
(
STACK_LEVEL
()
>
b
->
b_level
)
{
v
=
POP
();
Py_XDECREF
(
v
);
...
...
@@ -2145,7 +2164,8 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
PUSH
(
exc
);
}
else
{
if
(
why
==
WHY_RETURN
)
if
(
why
==
WHY_RETURN
||
why
==
CONTINUE_LOOP
)
PUSH
(
retval
);
v
=
PyInt_FromLong
((
long
)
why
);
PUSH
(
v
);
...
...
Python/compile.c
View file @
3faa52ec
...
...
@@ -5,7 +5,7 @@
XXX add __doc__ attribute == co_doc to code object attributes?
XXX (it's currently the first item of the co_const tuple)
XXX Generate simple jump for break/return outside 'try...finally'
XXX Allow 'continue' inside try-finally
XXX Allow 'continue' inside
finally clause of
try-finally
XXX New opcode for loading the initial index for a for loop
XXX other JAR tricks?
*/
...
...
@@ -3247,19 +3247,24 @@ com_continue_stmt(struct compiling *c, node *n)
}
else
{
int
j
;
for
(
j
=
0
;
j
<=
i
;
++
j
)
{
for
(
j
=
i
-
1
;
j
>=
0
;
--
j
)
{
if
(
c
->
c_block
[
j
]
==
SETUP_LOOP
)
break
;
}
if
(
j
<
i
+
1
)
{
if
(
j
>=
0
)
{
/* there is a loop, but something interferes */
for
(
++
j
;
j
<=
i
;
++
j
)
{
if
(
c
->
c_block
[
i
]
==
SETUP_EXCEPT
||
c
->
c_block
[
i
]
==
SETUP_FINALLY
)
{
com_
error
(
c
,
PyExc_SyntaxError
,
"'continue' not supported inside 'try' clause"
);
for
(
;
i
>
j
;
--
i
)
{
if
(
c
->
c_block
[
i
]
==
SETUP_EXCEPT
||
c
->
c_block
[
i
]
==
SETUP_FINALLY
)
{
com_
addoparg
(
c
,
CONTINUE_LOOP
,
c
->
c_begin
);
return
;
}
if
(
c
->
c_block
[
i
]
==
END_FINALLY
)
{
com_error
(
c
,
PyExc_SyntaxError
,
"'continue' not supported inside 'finally' clause"
);
return
;
}
}
}
com_error
(
c
,
PyExc_SyntaxError
,
...
...
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