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
...
@@ -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
{
try
}
clause, the exception is temporarily saved, the
\keyword
{
finally
}
clause is executed, and then the saved exception is
\keyword
{
finally
}
clause is executed, and then the saved exception is
re-raised. If the
\keyword
{
finally
}
clause raises another exception or
re-raised. If the
\keyword
{
finally
}
clause raises another exception or
executes a
\keyword
{
return
}
,
\keyword
{
break
}
or
\keyword
{
continue
}
statement,
executes a
\keyword
{
return
}
or
\keyword
{
break
}
statement, the saved
the saved exception is lost. The exception information is not
exception is lost. A
\keyword
{
continue
}
statement is illegal in the
available to the program during execution of the
\keyword
{
finally
}
\keyword
{
finally
}
clause. (The reason is a problem with the current
clause.
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
}
\kwindex
{
finally
}
When a
\keyword
{
return
}
or
\keyword
{
break
}
statement is executed in the
When a
\keyword
{
return
}
,
\keyword
{
break
}
or
\keyword
{
continue
}
statement is
\keyword
{
try
}
suite of a
\keyword
{
try
}
...
\keyword
{
finally
}
statement, the
executed in the
\keyword
{
try
}
suite of a
\keyword
{
try
}
...
\keyword
{
finally
}
\keyword
{
finally
}
clause is also executed `on the way out.'
A
statement, the
\keyword
{
finally
}
clause is also executed `on the way out.'
A
\keyword
{
continue
}
statement is illegal in the
\keyword
{
try
}
clause. (The
\keyword
{
continue
}
statement is illegal in the
\keyword
{
finally
}
clause.
reason is a problem with the current implementation --- this
(The
reason is a problem with the current implementation --- this
restriction may be lifted in the future).
restriction may be lifted in the future).
\stindex
{
return
}
\stindex
{
return
}
\stindex
{
break
}
\stindex
{
break
}
...
...
Include/opcode.h
View file @
3faa52ec
...
@@ -104,6 +104,7 @@ extern "C" {
...
@@ -104,6 +104,7 @@ extern "C" {
#define LOAD_GLOBAL 116
/* Index in name list */
#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_LOOP 120
/* Target address (absolute) */
#define SETUP_EXCEPT 121
/* "" */
#define SETUP_EXCEPT 121
/* "" */
#define SETUP_FINALLY 122
/* "" */
#define SETUP_FINALLY 122
/* "" */
...
...
Lib/dis.py
View file @
3faa52ec
...
@@ -259,6 +259,7 @@ jrel_op('FOR_LOOP', 114) # Number of bytes to skip
...
@@ -259,6 +259,7 @@ jrel_op('FOR_LOOP', 114) # Number of bytes to skip
name_op
(
'LOAD_GLOBAL'
,
116
)
# Index in name list
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_LOOP'
,
120
)
# Distance to target address
jrel_op
(
'SETUP_EXCEPT'
,
121
)
# ""
jrel_op
(
'SETUP_EXCEPT'
,
121
)
# ""
jrel_op
(
'SETUP_FINALLY'
,
122
)
# ""
jrel_op
(
'SETUP_FINALLY'
,
122
)
# ""
...
...
Lib/test/output/test_exceptions
View file @
3faa52ec
...
@@ -27,11 +27,7 @@ RuntimeError
...
@@ -27,11 +27,7 @@ RuntimeError
(not used any more?)
(not used any more?)
spam
spam
SyntaxError
SyntaxError
'continue' not supported inside 'try' clause
'continue' not supported inside 'finally' clause
ok
'continue' not supported inside 'try' clause
ok
'continue' not supported inside 'try' clause
ok
ok
'continue' not properly in loop
'continue' not properly in loop
ok
ok
...
...
Lib/test/output/test_grammar
View file @
3faa52ec
...
@@ -33,6 +33,8 @@ pass_stmt
...
@@ -33,6 +33,8 @@ pass_stmt
flow_stmt
flow_stmt
break_stmt
break_stmt
continue_stmt
continue_stmt
continue + try/except ok
continue + try/finally ok
return_stmt
return_stmt
raise_stmt
raise_stmt
import_stmt
import_stmt
...
...
Lib/test/test_exceptions.py
View file @
3faa52ec
...
@@ -104,28 +104,11 @@ def ckmsg(src, msg):
...
@@ -104,28 +104,11 @@ def ckmsg(src, msg):
s
=
'''
\
s
=
'''
\
while 1:
while 1:
try:
try:
continue
except:
pass
'''
ckmsg
(
s
,
"'continue' not supported inside 'try' clause"
)
s
=
'''
\
while 1:
try:
continue
finally:
pass
pass
'''
ckmsg
(
s
,
"'continue' not supported inside 'try' clause"
)
s
=
'''
\
while 1:
try:
if 1:
continue
finally:
finally:
pass
continue
'''
'''
ckmsg
(
s
,
"'continue' not supported inside '
tr
y' clause"
)
ckmsg
(
s
,
"'continue' not supported inside '
finall
y' clause"
)
s
=
'''
\
s
=
'''
\
try:
try:
continue
continue
...
...
Lib/test/test_grammar.py
View file @
3faa52ec
...
@@ -349,6 +349,25 @@ print 'continue_stmt' # 'continue'
...
@@ -349,6 +349,25 @@ print 'continue_stmt' # 'continue'
i
=
1
i
=
1
while
i
:
i
=
0
;
continue
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]
print
'return_stmt'
# 'return' [testlist]
def
g1
():
return
def
g1
():
return
def
g2
():
return
1
def
g2
():
return
1
...
...
Python/ceval.c
View file @
3faa52ec
...
@@ -322,7 +322,8 @@ enum why_code {
...
@@ -322,7 +322,8 @@ enum why_code {
WHY_EXCEPTION
,
/* Exception occurred */
WHY_EXCEPTION
,
/* Exception occurred */
WHY_RERAISE
,
/* Exception re-raised by 'finally' */
WHY_RERAISE
,
/* Exception re-raised by 'finally' */
WHY_RETURN
,
/* 'return' statement */
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
*
);
static
enum
why_code
do_raise
(
PyObject
*
,
PyObject
*
,
PyObject
*
);
...
@@ -1357,6 +1358,11 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
...
@@ -1357,6 +1358,11 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
case
BREAK_LOOP
:
case
BREAK_LOOP
:
why
=
WHY_BREAK
;
why
=
WHY_BREAK
;
break
;
break
;
case
CONTINUE_LOOP
:
retval
=
PyInt_FromLong
(
oparg
);
why
=
WHY_CONTINUE
;
break
;
case
RAISE_VARARGS
:
case
RAISE_VARARGS
:
u
=
v
=
w
=
NULL
;
u
=
v
=
w
=
NULL
;
...
@@ -1419,7 +1425,8 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
...
@@ -1419,7 +1425,8 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
v
=
POP
();
v
=
POP
();
if
(
PyInt_Check
(
v
))
{
if
(
PyInt_Check
(
v
))
{
why
=
(
enum
why_code
)
PyInt_AsLong
(
v
);
why
=
(
enum
why_code
)
PyInt_AsLong
(
v
);
if
(
why
==
WHY_RETURN
)
if
(
why
==
WHY_RETURN
||
why
==
CONTINUE_LOOP
)
retval
=
POP
();
retval
=
POP
();
}
}
else
if
(
PyString_Check
(
v
)
||
PyClass_Check
(
v
))
{
else
if
(
PyString_Check
(
v
)
||
PyClass_Check
(
v
))
{
...
@@ -1834,7 +1841,7 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
...
@@ -1834,7 +1841,7 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
case
SETUP_EXCEPT
:
case
SETUP_EXCEPT
:
case
SETUP_FINALLY
:
case
SETUP_FINALLY
:
PyFrame_BlockSetup
(
f
,
opcode
,
INSTR_OFFSET
()
+
oparg
,
PyFrame_BlockSetup
(
f
,
opcode
,
INSTR_OFFSET
()
+
oparg
,
STACK_LEVEL
());
STACK_LEVEL
());
continue
;
continue
;
case
SET_LINENO
:
case
SET_LINENO
:
...
@@ -2110,6 +2117,18 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
...
@@ -2110,6 +2117,18 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
while
(
why
!=
WHY_NOT
&&
f
->
f_iblock
>
0
)
{
while
(
why
!=
WHY_NOT
&&
f
->
f_iblock
>
0
)
{
PyTryBlock
*
b
=
PyFrame_BlockPop
(
f
);
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
)
{
while
(
STACK_LEVEL
()
>
b
->
b_level
)
{
v
=
POP
();
v
=
POP
();
Py_XDECREF
(
v
);
Py_XDECREF
(
v
);
...
@@ -2145,7 +2164,8 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
...
@@ -2145,7 +2164,8 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
PUSH
(
exc
);
PUSH
(
exc
);
}
}
else
{
else
{
if
(
why
==
WHY_RETURN
)
if
(
why
==
WHY_RETURN
||
why
==
CONTINUE_LOOP
)
PUSH
(
retval
);
PUSH
(
retval
);
v
=
PyInt_FromLong
((
long
)
why
);
v
=
PyInt_FromLong
((
long
)
why
);
PUSH
(
v
);
PUSH
(
v
);
...
...
Python/compile.c
View file @
3faa52ec
...
@@ -5,7 +5,7 @@
...
@@ -5,7 +5,7 @@
XXX add __doc__ attribute == co_doc to code object attributes?
XXX add __doc__ attribute == co_doc to code object attributes?
XXX (it's currently the first item of the co_const tuple)
XXX (it's currently the first item of the co_const tuple)
XXX Generate simple jump for break/return outside 'try...finally'
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 New opcode for loading the initial index for a for loop
XXX other JAR tricks?
XXX other JAR tricks?
*/
*/
...
@@ -3247,19 +3247,24 @@ com_continue_stmt(struct compiling *c, node *n)
...
@@ -3247,19 +3247,24 @@ com_continue_stmt(struct compiling *c, node *n)
}
}
else
{
else
{
int
j
;
int
j
;
for
(
j
=
0
;
j
<=
i
;
++
j
)
{
for
(
j
=
i
-
1
;
j
>=
0
;
--
j
)
{
if
(
c
->
c_block
[
j
]
==
SETUP_LOOP
)
if
(
c
->
c_block
[
j
]
==
SETUP_LOOP
)
break
;
break
;
}
}
if
(
j
<
i
+
1
)
{
if
(
j
>=
0
)
{
/* there is a loop, but something interferes */
/* there is a loop, but something interferes */
for
(
++
j
;
j
<=
i
;
++
j
)
{
for
(
;
i
>
j
;
--
i
)
{
if
(
c
->
c_block
[
i
]
==
SETUP_EXCEPT
if
(
c
->
c_block
[
i
]
==
SETUP_EXCEPT
||
||
c
->
c_block
[
i
]
==
SETUP_FINALLY
)
{
c
->
c_block
[
i
]
==
SETUP_FINALLY
)
{
com_
error
(
c
,
PyExc_SyntaxError
,
com_
addoparg
(
c
,
CONTINUE_LOOP
,
"'continue' not supported inside 'try' clause"
);
c
->
c_begin
);
return
;
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
,
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