Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c5fe5eb

Browse files
committed
SF bug 567538: Generator can crash the interpreter (Finn Bock).
This was a simple typo. Strange that the compiler didn't catch it! Instead of WHY_CONTINUE, two tests used CONTINUE_LOOP, which isn't a why_code at all, but an opcode; but even though 'why' is declared as an enum, comparing it to an int is apparently not even worth a warning -- not in gcc, and not in VC++. :-( Will fix in 2.2 too.
1 parent 969de45 commit c5fe5eb

3 files changed

Lines changed: 25 additions & 2 deletions

File tree

Lib/test/test_generators.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -805,6 +805,26 @@
805805
... yield 2 # because it's a generator
806806
Traceback (most recent call last):
807807
SyntaxError: 'return' with argument inside generator (<string>, line 8)
808+
809+
This one caused a crash (see SF bug 567538):
810+
811+
>>> def f():
812+
... for i in range(3):
813+
... try:
814+
... continue
815+
... finally:
816+
... yield i
817+
...
818+
>>> g = f()
819+
>>> print g.next()
820+
0
821+
>>> print g.next()
822+
1
823+
>>> print g.next()
824+
2
825+
>>> print g.next()
826+
Traceback (most recent call last):
827+
StopIteration
808828
"""
809829

810830
# conjoin is a simple backtracking generator, named in honor of Icon's

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ Type/class unification and new-style classes
66

77
Core and builtins
88

9+
- Fixed a bug with a continue inside a try block and a yield in the
10+
finally clause. [SF bug 567538]
11+
912
- Most builtin sequences now support "extended slices", i.e. slices
1013
with a third "stride" parameter. For example, "range(10)[1:6:2]"
1114
evaluates to [1, 3, 5].

Python/ceval.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1543,7 +1543,7 @@ eval_frame(PyFrameObject *f)
15431543
why = (enum why_code) PyInt_AsLong(v);
15441544
if (why == WHY_RETURN ||
15451545
why == WHY_YIELD ||
1546-
why == CONTINUE_LOOP)
1546+
why == WHY_CONTINUE)
15471547
retval = POP();
15481548
}
15491549
else if (PyString_Check(v) || PyClass_Check(v)) {
@@ -2293,7 +2293,7 @@ eval_frame(PyFrameObject *f)
22932293
}
22942294
else {
22952295
if (why == WHY_RETURN ||
2296-
why == CONTINUE_LOOP)
2296+
why == WHY_CONTINUE)
22972297
PUSH(retval);
22982298
v = PyInt_FromLong((long)why);
22992299
PUSH(v);

0 commit comments

Comments
 (0)