[pypy-svn] pypy default: Extend test_trace_generator_finalisation to check for the correct
arigo
commits-noreply at bitbucket.org
Mon Feb 7 15:10:58 CET 2011
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r41668:9dc525f2d8e4
Date: 2011-02-07 15:10 +0100
http://bitbucket.org/pypy/pypy/changeset/9dc525f2d8e4/
Log: Extend test_trace_generator_finalisation to check for the correct
order of the events: generator.throw() used to get the tracing
events "exception" followed by "call", whereas on CPython it is the
opposite order. Fix it.
diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py
--- a/pypy/interpreter/generator.py
+++ b/pypy/interpreter/generator.py
@@ -55,7 +55,7 @@
frame = self.frame
if frame is None:
# xxx a bit ad-hoc, but we don't want to go inside
- # execute_generator_frame() if the frame is actually finished
+ # execute_frame() if the frame is actually finished
if operr is None:
operr = OperationError(space.w_StopIteration, space.w_None)
raise operr
@@ -72,7 +72,7 @@
self.running = True
try:
try:
- w_result = frame.execute_generator_frame(w_arg, operr)
+ w_result = frame.execute_frame(w_arg, operr)
except OperationError:
# errors finish a frame
self.frame = None
diff --git a/pypy/interpreter/test/test_pyframe.py b/pypy/interpreter/test/test_pyframe.py
--- a/pypy/interpreter/test/test_pyframe.py
+++ b/pypy/interpreter/test/test_pyframe.py
@@ -279,12 +279,13 @@
def test_trace_generator_finalisation(self):
- # XXX expand to check more aspects
import sys
l = []
+ got_exc = []
def trace(frame, event, arg):
+ l.append((frame.f_lineno, event))
if event == 'exception':
- l.append(arg)
+ got_exc.append(arg)
return trace
d = {}
@@ -308,8 +309,22 @@
sys.settrace(trace)
f()
sys.settrace(None)
- assert len(l) == 1
- assert issubclass(l[0][0], GeneratorExit)
+ assert len(got_exc) == 1
+ assert issubclass(got_exc[0][0], GeneratorExit)
+ assert l == [(8, 'call'),
+ (9, 'line'),
+ (10, 'line'),
+ (11, 'line'),
+ (2, 'call'),
+ (3, 'line'),
+ (4, 'line'),
+ (4, 'return'),
+ (12, 'line'),
+ (4, 'call'),
+ (4, 'exception'),
+ (6, 'line'),
+ (6, 'return'),
+ (12, 'return')]
def test_dont_trace_on_reraise(self):
import sys
diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py
--- a/pypy/interpreter/pyframe.py
+++ b/pypy/interpreter/pyframe.py
@@ -125,17 +125,12 @@
else:
return self.execute_frame()
- def execute_generator_frame(self, w_inputvalue, operr=None):
- if operr is not None:
- ec = self.space.getexecutioncontext()
- next_instr = self.handle_operation_error(ec, operr)
- self.last_instr = intmask(next_instr - 1)
- elif self.last_instr != -1:
- self.pushvalue(w_inputvalue)
- return self.execute_frame()
-
- def execute_frame(self):
- """Execute this frame. Main entry point to the interpreter."""
+ def execute_frame(self, w_inputvalue=None, operr=None):
+ """Execute this frame. Main entry point to the interpreter.
+ The optional arguments are there to handle a generator's frame:
+ w_inputvalue is for generator.send()) and operr is for
+ generator.throw()).
+ """
# the following 'assert' is an annotation hint: it hides from
# the annotator all methods that are defined in PyFrame but
# overridden in the {,Host}FrameClass subclasses of PyFrame.
@@ -145,10 +140,19 @@
executioncontext.enter(self)
try:
executioncontext.call_trace(self)
- # Execution starts just after the last_instr. Initially,
- # last_instr is -1. After a generator suspends it points to
- # the YIELD_VALUE instruction.
- next_instr = self.last_instr + 1
+ #
+ if operr is not None:
+ ec = self.space.getexecutioncontext()
+ next_instr = self.handle_operation_error(ec, operr)
+ self.last_instr = intmask(next_instr - 1)
+ else:
+ # Execution starts just after the last_instr. Initially,
+ # last_instr is -1. After a generator suspends it points to
+ # the YIELD_VALUE instruction.
+ next_instr = self.last_instr + 1
+ if next_instr != 0:
+ self.pushvalue(w_inputvalue)
+ #
try:
w_exitvalue = self.dispatch(self.pycode, next_instr,
executioncontext)
More information about the Pypy-commit
mailing list