Skip to content

Commit d3ee00a

Browse files
committed
implement PEP 479
1 parent eb1f08e commit d3ee00a

File tree

2 files changed

+26
-9
lines changed

2 files changed

+26
-9
lines changed

graalpython/com.oracle.graal.python.test/src/tests/test_generators.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -207,18 +207,19 @@ def gen():
207207
next(g)
208208
next(g)
209209
self.assertEqual(next(g), "done")
210-
211210

212-
def test_stopiteration_warning(self):
211+
@unittest.skipIf(sys.version_info.minor < 7, "Requires Python 3.7+")
212+
def test_stopiteration_error(self):
213213
# See also PEP 479.
214214

215215
def gen():
216216
raise StopIteration
217217
yield
218218

219-
with self.assertRaises(StopIteration):
219+
with self.assertRaisesRegex(RuntimeError, 'raised StopIteration'):
220220
next(gen())
221221

222+
@unittest.skipIf(sys.version_info.minor < 7, "Requires Python 3.7+")
222223
def test_tutorial_stopiteration(self):
223224
# Raise StopIteration" stops the generator too:
224225

@@ -230,13 +231,9 @@ def f():
230231
g = f()
231232
self.assertEqual(next(g), 1)
232233

233-
with self.assertRaises(StopIteration):
234+
with self.assertRaisesRegex(RuntimeError, 'raised StopIteration'):
234235
next(g)
235236

236-
with self.assertRaises(StopIteration):
237-
# This time StopIteration isn't raised from the generator's body,
238-
# hence no warning.
239-
next(g)
240237

241238
# def test_return_tuple(self):
242239
# def g():

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/generator/GeneratorReturnTargetNode.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,20 @@
2525
*/
2626
package com.oracle.graal.python.nodes.generator;
2727

28+
import static com.oracle.graal.python.runtime.exception.PythonErrorType.RuntimeError;
2829
import static com.oracle.graal.python.runtime.exception.PythonErrorType.StopIteration;
2930

3031
import com.oracle.graal.python.builtins.objects.PNone;
3132
import com.oracle.graal.python.nodes.PRaiseNode;
3233
import com.oracle.graal.python.nodes.expression.ExpressionNode;
34+
import com.oracle.graal.python.nodes.object.IsBuiltinClassProfile;
3335
import com.oracle.graal.python.nodes.statement.StatementNode;
36+
import com.oracle.graal.python.runtime.exception.PException;
3437
import com.oracle.graal.python.runtime.exception.ReturnException;
3538
import com.oracle.graal.python.runtime.exception.YieldException;
3639
import com.oracle.graal.python.runtime.object.PythonObjectFactory;
3740
import com.oracle.truffle.api.CompilerDirectives;
41+
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
3842
import com.oracle.truffle.api.frame.VirtualFrame;
3943
import com.oracle.truffle.api.profiles.BranchProfile;
4044

@@ -50,6 +54,7 @@ public final class GeneratorReturnTargetNode extends ExpressionNode implements G
5054
private final BranchProfile returnProfile = BranchProfile.create();
5155
private final BranchProfile fallthroughProfile = BranchProfile.create();
5256
private final BranchProfile yieldProfile = BranchProfile.create();
57+
@CompilationFinal private IsBuiltinClassProfile errorProfile;
5358

5459
private final int flagSlot;
5560

@@ -68,6 +73,14 @@ public int getFlagSlot() {
6873
return flagSlot;
6974
}
7075

76+
private IsBuiltinClassProfile getErrorProfile() {
77+
if (errorProfile == null) {
78+
CompilerDirectives.transferToInterpreterAndInvalidate();
79+
errorProfile = IsBuiltinClassProfile.create();
80+
}
81+
return errorProfile;
82+
}
83+
7184
@Override
7285
public Object execute(VirtualFrame frame) {
7386
if (!gen.isActive(frame, flagSlot)) {
@@ -76,7 +89,14 @@ public Object execute(VirtualFrame frame) {
7689
}
7790

7891
try {
79-
body.executeVoid(frame);
92+
try {
93+
body.executeVoid(frame);
94+
} catch (PException pe) {
95+
// PEP 479 - StopIteration raised from generator body needs to be wrapped in
96+
// RuntimeError
97+
pe.expectStopIteration(getErrorProfile());
98+
throw raise.raise(RuntimeError, pe.getExceptionObject(), "generator raised StopIteration");
99+
}
80100
fallthroughProfile.enter();
81101
throw raise.raise(StopIteration);
82102
} catch (YieldException eye) {

0 commit comments

Comments
 (0)