[pypy-commit] pypy apptest-file: Convert test_pyframe.py to new-style apptests
rlamy
pypy.commits at gmail.com
Fri Apr 13 16:39:39 EDT 2018
Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: apptest-file
Changeset: r94315:00ee97dd7467
Date: 2018-04-13 21:38 +0100
http://bitbucket.org/pypy/pypy/changeset/00ee97dd7467/
Log: Convert test_pyframe.py to new-style apptests
diff --git a/pypy/interpreter/test/apptest_pyframe.py b/pypy/interpreter/test/apptest_pyframe.py
new file mode 100644
--- /dev/null
+++ b/pypy/interpreter/test/apptest_pyframe.py
@@ -0,0 +1,575 @@
+import pytest
+
+ at pytest.fixture
+def tempfile(tmpdir):
+ return str(tmpdir / 'tempfile1')
+
+def test_f_locals():
+ import sys
+ f = sys._getframe()
+ assert f.f_locals is locals()
+
+def test_f_globals():
+ import sys
+ f = sys._getframe()
+ assert f.f_globals is globals()
+ pytest.raises(TypeError, "f.f_globals = globals()")
+
+def test_f_builtins():
+ import sys, __builtin__
+ f = sys._getframe()
+ assert f.f_builtins is __builtin__.__dict__
+
+def test_f_code():
+ def g():
+ import sys
+ f = sys._getframe()
+ return f.f_code
+ assert g() is g.func_code
+
+def test_f_trace_del():
+ import sys
+ f = sys._getframe()
+ del f.f_trace
+ assert f.f_trace is None
+
+def test_f_lineno():
+ def g():
+ import sys
+ f = sys._getframe()
+ x = f.f_lineno
+ y = f.f_lineno
+ z = f.f_lineno
+ return [x, y, z]
+ origin = g.func_code.co_firstlineno
+ assert g() == [origin+3, origin+4, origin+5]
+
+def test_f_lineno_set(tempfile):
+ def tracer(f, *args):
+ def y(f, *args):
+ return y
+ def x(f, *args):
+ f.f_lineno += 1
+ return y # "return None" should have the same effect, but see
+ # test_local_trace_function_returning_None_ignored
+ return x
+
+ open # force fetching of this name now
+
+ def function():
+ xyz
+ with open(tempfile, 'w') as f:
+ pass
+ return 3
+
+ import sys
+ sys.settrace(tracer)
+ function()
+ sys.settrace(None)
+ # assert did not crash
+
+def test_f_lineno_set_firstline():
+ seen = []
+ def tracer(f, event, *args):
+ seen.append((event, f.f_lineno))
+ if len(seen) == 5:
+ f.f_lineno = 1 # bug shown only when setting lineno to 1
+ return tracer
+
+ def g():
+ import sys
+ sys.settrace(tracer)
+ exec "x=1\ny=x+1\nz=y+1\nt=z+1\ns=t+1\n" in {}
+ sys.settrace(None)
+
+ g()
+ assert seen == [('call', 1),
+ ('line', 1),
+ ('line', 2),
+ ('line', 3),
+ ('line', 4),
+ ('line', 2),
+ ('line', 3),
+ ('line', 4),
+ ('line', 5),
+ ('return', 5)]
+
+def test_f_back():
+ import sys
+ def f():
+ assert sys._getframe().f_code.co_name == g()
+ def g():
+ return sys._getframe().f_back.f_code.co_name
+ f()
+
+def test_f_back_virtualref():
+ import sys
+ def f():
+ return g()
+ def g():
+ return sys._getframe()
+ frame = f()
+ assert frame.f_back.f_code.co_name == 'f'
+
+def test_f_exc_xxx():
+ import sys
+
+ class OuterException(Exception):
+ pass
+ class InnerException(Exception):
+ pass
+
+ def g(exc_info):
+ f = sys._getframe()
+ assert f.f_exc_type is None
+ assert f.f_exc_value is None
+ assert f.f_exc_traceback is None
+ try:
+ raise InnerException
+ except:
+ assert f.f_exc_type is exc_info[0]
+ assert f.f_exc_value is exc_info[1]
+ assert f.f_exc_traceback is exc_info[2]
+ try:
+ raise OuterException
+ except:
+ g(sys.exc_info())
+
+def test_virtualref_through_traceback():
+ import sys
+ def g():
+ try:
+ raise ValueError
+ except:
+ _, _, tb = sys.exc_info()
+ return tb
+ def f():
+ return g()
+ #
+ tb = f()
+ assert tb.tb_frame.f_code.co_name == 'g'
+ assert tb.tb_frame.f_back.f_code.co_name == 'f'
+
+def test_trace_basic():
+ import sys
+ l = []
+ class Tracer:
+ def __init__(self, i):
+ self.i = i
+ def trace(self, frame, event, arg):
+ l.append((self.i, frame.f_code.co_name, event, arg))
+ if frame.f_code.co_name == 'g2':
+ return None # don't trace g2
+ return Tracer(self.i+1).trace
+ def g3(n):
+ n -= 5
+ return n
+ def g2(n):
+ n += g3(2)
+ n += g3(7)
+ return n
+ def g(n):
+ n += g2(3)
+ return n
+ def f(n):
+ n = g(n)
+ return n * 7
+ sys.settrace(Tracer(0).trace)
+ x = f(4)
+ sys.settrace(None)
+ assert x == 42
+ print l
+ assert l == [(0, 'f', 'call', None),
+ (1, 'f', 'line', None),
+ (0, 'g', 'call', None),
+ (1, 'g', 'line', None),
+ (0, 'g2', 'call', None),
+ (0, 'g3', 'call', None),
+ (1, 'g3', 'line', None),
+ (2, 'g3', 'line', None),
+ (3, 'g3', 'return', -3),
+ (0, 'g3', 'call', None),
+ (1, 'g3', 'line', None),
+ (2, 'g3', 'line', None),
+ (3, 'g3', 'return', 2),
+ (2, 'g', 'line', None),
+ (3, 'g', 'return', 6),
+ (2, 'f', 'line', None),
+ (3, 'f', 'return', 42)]
+
+def test_trace_exc():
+ import sys
+ l = []
+ def ltrace(a,b,c):
+ if b == 'exception':
+ l.append(c)
+ return ltrace
+ def trace(a,b,c): return ltrace
+ def f():
+ try:
+ raise Exception
+ except:
+ pass
+ sys.settrace(trace)
+ f()
+ sys.settrace(None)
+ assert len(l) == 1
+ assert isinstance(l[0][1], Exception)
+
+def test_trace_ignore_hidden():
+ import sys
+ import _testing
+
+ l = []
+ def trace(a,b,c):
+ l.append((a,b,c))
+
+ def f():
+ h = _testing.Hidden()
+ r = h.meth()
+ return r
+
+ sys.settrace(trace)
+ res = f()
+ sys.settrace(None)
+ assert len(l) == 1
+ assert l[0][1] == 'call'
+ assert res == 'hidden' # sanity
+
+def test_trace_hidden_prints(tempfile):
+ import sys
+
+ l = []
+ def trace(a,b,c):
+ l.append((a,b,c))
+ return trace
+
+ outputf = open(tempfile, 'w')
+ def f():
+ print >> outputf, 1
+ print >> outputf, 2
+ print >> outputf, 3
+ return "that's the return value"
+
+ sys.settrace(trace)
+ f()
+ sys.settrace(None)
+ outputf.close()
+ # should get 1 "call", 3 "line" and 1 "return" events, and no call
+ # or return for the internal app-level implementation of 'print'
+ assert len(l) == 6
+ assert [what for (frame, what, arg) in l] == [
+ 'call', 'line', 'line', 'line', 'line', 'return']
+ assert l[-1][2] == "that's the return value"
+
+def test_trace_return_exc():
+ import sys
+ l = []
+ def trace(a,b,c):
+ if b in ('exception', 'return'):
+ l.append((b, c))
+ return trace
+
+ def g():
+ raise Exception
+ def f():
+ try:
+ g()
+ except:
+ pass
+ sys.settrace(trace)
+ f()
+ sys.settrace(None)
+ assert len(l) == 4
+ assert l[0][0] == 'exception'
+ assert isinstance(l[0][1][1], Exception)
+ assert l[1] == ('return', None)
+ assert l[2][0] == 'exception'
+ assert isinstance(l[2][1][1], Exception)
+ assert l[3] == ('return', None)
+
+def test_trace_raises_on_return():
+ import sys
+ def trace(frame, event, arg):
+ if event == 'return':
+ raise ValueError
+ else:
+ return trace
+
+ def f(): return 1
+
+ for i in xrange(sys.getrecursionlimit() + 1):
+ sys.settrace(trace)
+ try:
+ f()
+ except ValueError:
+ pass
+
+def test_trace_try_finally():
+ import sys
+ l = []
+ def trace(frame, event, arg):
+ if event == 'exception':
+ l.append(arg)
+ return trace
+
+ def g():
+ try:
+ raise Exception
+ finally:
+ pass
+
+ def f():
+ try:
+ g()
+ except:
+ pass
+
+ sys.settrace(trace)
+ f()
+ sys.settrace(None)
+ assert len(l) == 2
+ assert issubclass(l[0][0], Exception)
+ assert issubclass(l[1][0], Exception)
+
+def test_trace_raise_three_arg():
+ import sys
+ l = []
+ def trace(frame, event, arg):
+ if event == 'exception':
+ l.append(arg)
+ return trace
+
+ def g():
+ try:
+ raise Exception
+ except Exception as e:
+ import sys
+ raise Exception, e, sys.exc_info()[2]
+
+ def f():
+ try:
+ g()
+ except:
+ pass
+
+ sys.settrace(trace)
+ f()
+ sys.settrace(None)
+ assert len(l) == 2
+ assert issubclass(l[0][0], Exception)
+ assert issubclass(l[1][0], Exception)
+
+def test_trace_generator_finalisation():
+ import sys
+ l = []
+ got_exc = []
+ def trace(frame, event, arg):
+ l.append((frame.f_lineno, event))
+ if event == 'exception':
+ got_exc.append(arg)
+ return trace
+
+ d = {}
+ exec """if 1:
+ def g():
+ try:
+ yield True
+ finally:
+ pass
+
+ def f():
+ try:
+ gen = g()
+ gen.next()
+ gen.close()
+ except:
+ pass
+ """ in d
+ f = d['f']
+
+ sys.settrace(trace)
+ f()
+ sys.settrace(None)
+ 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():
+ import sys
+ l = []
+ def ltrace(a,b,c):
+ if b == 'exception':
+ l.append(c)
+ return ltrace
+ def trace(a,b,c): return ltrace
+ def f():
+ try:
+ 1/0
+ except:
+ try:
+ raise
+ except:
+ pass
+ sys.settrace(trace)
+ f()
+ sys.settrace(None)
+ assert len(l) == 1
+ assert issubclass(l[0][0], Exception)
+
+def test_dont_trace_on_raise_with_tb():
+ import sys
+ l = []
+ def ltrace(a,b,c):
+ if b == 'exception':
+ l.append(c)
+ return ltrace
+ def trace(a,b,c): return ltrace
+ def f():
+ try:
+ raise Exception
+ except:
+ return sys.exc_info()
+ def g():
+ exc, val, tb = f()
+ try:
+ raise exc, val, tb
+ except:
+ pass
+ sys.settrace(trace)
+ g()
+ sys.settrace(None)
+ assert len(l) == 1
+ assert isinstance(l[0][1], Exception)
+
+def test_trace_changes_locals():
+ import sys
+ def trace(frame, what, arg):
+ frame.f_locals['x'] = 42
+ return trace
+ def f(x):
+ return x
+ sys.settrace(trace)
+ res = f(1)
+ sys.settrace(None)
+ assert res == 42
+
+def test_set_unset_f_trace():
+ import sys
+ seen = []
+ def trace1(frame, what, arg):
+ seen.append((1, frame, frame.f_lineno, what, arg))
+ return trace1
+ def trace2(frame, what, arg):
+ seen.append((2, frame, frame.f_lineno, what, arg))
+ return trace2
+ def set_the_trace(f):
+ f.f_trace = trace1
+ sys.settrace(trace2)
+ len(seen) # take one line: should not be traced
+ f = sys._getframe()
+ set_the_trace(f)
+ len(seen) # take one line: should not be traced
+ len(seen) # take one line: should not be traced
+ sys.settrace(None) # and this line should be the last line traced
+ len(seen) # take one line
+ del f.f_trace
+ len(seen) # take one line
+ firstline = set_the_trace.func_code.co_firstlineno
+ assert seen == [(1, f, firstline + 6, 'line', None),
+ (1, f, firstline + 7, 'line', None),
+ (1, f, firstline + 8, 'line', None)]
+
+def test_locals2fast_freevar_bug():
+ import sys
+ def f(n):
+ class A(object):
+ def g(self):
+ return n
+ n = 42
+ return A()
+ res = f(10).g()
+ assert res == 10
+ #
+ def trace(*args):
+ return trace
+ sys.settrace(trace)
+ res = f(10).g()
+ sys.settrace(None)
+ assert res == 10
+
+def test_throw_trace_bug():
+ import sys
+ def f():
+ yield 5
+ gen = f()
+ assert next(gen) == 5
+ seen = []
+ def trace_func(frame, event, *args):
+ seen.append(event)
+ return trace_func
+ sys.settrace(trace_func)
+ try:
+ gen.throw(ValueError)
+ except ValueError:
+ pass
+ sys.settrace(None)
+ assert seen == ['call', 'exception', 'return']
+
+def test_generator_trace_stopiteration():
+ import sys
+ def f():
+ yield 5
+ gen = f()
+ assert next(gen) == 5
+ seen = []
+ def trace_func(frame, event, *args):
+ print('TRACE:', frame, event, args)
+ seen.append(event)
+ return trace_func
+ def g():
+ for x in gen:
+ never_entered
+ sys.settrace(trace_func)
+ g()
+ sys.settrace(None)
+ print 'seen:', seen
+ # on Python 3 we get an extra 'exception' when 'for' catches
+ # StopIteration
+ assert seen == ['call', 'line', 'call', 'return', 'return']
+
+def test_local_trace_function_returning_None_ignored():
+ # behave the same as CPython does, and in contradiction with
+ # the documentation.
+ def tracer(f, event, arg):
+ assert event == 'call'
+ return local_tracer
+
+ seen = []
+ def local_tracer(f, event, arg):
+ seen.append(event)
+ return None # but 'local_tracer' will be called again
+
+ def function():
+ a = 1
+ a = 2
+ a = 3
+
+ import sys
+ sys.settrace(tracer)
+ function()
+ sys.settrace(None)
+ assert seen == ["line", "line", "line", "return"]
diff --git a/pypy/interpreter/test/fixtures.py b/pypy/interpreter/test/fixtures.py
new file mode 100644
--- /dev/null
+++ b/pypy/interpreter/test/fixtures.py
@@ -0,0 +1,5 @@
+from _pytest.tmpdir import TempdirFactory
+
+def tempfile(space, config):
+ tmpdir = TempdirFactory(config).getbasetemp()
+ return space.newtext(str(tmpdir / 'tempfile1'))
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
@@ -1,4 +1,3 @@
-from rpython.tool import udir
from pypy.conftest import option
from pypy.interpreter.gateway import interp2app
@@ -9,8 +8,6 @@
def setup_class(cls):
space = cls.space
- cls.w_udir = cls.space.wrap(str(udir.udir))
- cls.w_tempfile1 = cls.space.wrap(str(udir.udir.join('tempfile1')))
if not option.runappdirect:
w_call_further = cls.space.appexec([], """():
def call_further(f):
@@ -25,113 +22,6 @@
# test for the presence of the attributes, not functionality
- def test_f_locals(self):
- import sys
- f = sys._getframe()
- assert f.f_locals is locals()
-
- def test_f_globals(self):
- import sys
- f = sys._getframe()
- assert f.f_globals is globals()
- raises(TypeError, "f.f_globals = globals()")
-
- def test_f_builtins(self):
- import sys, __builtin__
- f = sys._getframe()
- assert f.f_builtins is __builtin__.__dict__
-
- def test_f_code(self):
- def g():
- import sys
- f = sys._getframe()
- return f.f_code
- assert g() is g.func_code
-
- def test_f_trace_del(self):
- import sys
- f = sys._getframe()
- del f.f_trace
- assert f.f_trace is None
-
- def test_f_lineno(self):
- def g():
- import sys
- f = sys._getframe()
- x = f.f_lineno
- y = f.f_lineno
- z = f.f_lineno
- return [x, y, z]
- origin = g.func_code.co_firstlineno
- assert g() == [origin+3, origin+4, origin+5]
-
- def test_f_lineno_set(self):
- def tracer(f, *args):
- def y(f, *args):
- return y
- def x(f, *args):
- f.f_lineno += 1
- return y # "return None" should have the same effect, but see
- # test_local_trace_function_returning_None_ignored
- return x
-
- open # force fetching of this name now
-
- def function():
- xyz
- with open(self.tempfile1, 'w') as f:
- pass
- return 3
-
- import sys
- sys.settrace(tracer)
- function()
- sys.settrace(None)
- # assert did not crash
-
- def test_f_lineno_set_firstline(self):
- seen = []
- def tracer(f, event, *args):
- seen.append((event, f.f_lineno))
- if len(seen) == 5:
- f.f_lineno = 1 # bug shown only when setting lineno to 1
- return tracer
-
- def g():
- import sys
- sys.settrace(tracer)
- exec "x=1\ny=x+1\nz=y+1\nt=z+1\ns=t+1\n" in {}
- sys.settrace(None)
-
- g()
- assert seen == [('call', 1),
- ('line', 1),
- ('line', 2),
- ('line', 3),
- ('line', 4),
- ('line', 2),
- ('line', 3),
- ('line', 4),
- ('line', 5),
- ('return', 5)]
-
- def test_f_back(self):
- import sys
- def f():
- assert sys._getframe().f_code.co_name == g()
- def g():
- return sys._getframe().f_back.f_code.co_name
- f()
-
- def test_f_back_virtualref(self):
- import sys
- def f():
- return g()
- def g():
- return sys._getframe()
- frame = f()
- assert frame.f_back.f_code.co_name == 'f'
-
def test_f_back_hidden(self):
if not hasattr(self, 'call_further'):
skip("not for runappdirect testing")
@@ -148,362 +38,6 @@
assert f1bis is f1
assert f0.f_back is f1
- def test_f_exc_xxx(self):
- import sys
-
- class OuterException(Exception):
- pass
- class InnerException(Exception):
- pass
-
- def g(exc_info):
- f = sys._getframe()
- assert f.f_exc_type is None
- assert f.f_exc_value is None
- assert f.f_exc_traceback is None
- try:
- raise InnerException
- except:
- assert f.f_exc_type is exc_info[0]
- assert f.f_exc_value is exc_info[1]
- assert f.f_exc_traceback is exc_info[2]
- try:
- raise OuterException
- except:
- g(sys.exc_info())
-
- def test_virtualref_through_traceback(self):
- import sys
- def g():
- try:
- raise ValueError
- except:
- _, _, tb = sys.exc_info()
- return tb
- def f():
- return g()
- #
- tb = f()
- assert tb.tb_frame.f_code.co_name == 'g'
- assert tb.tb_frame.f_back.f_code.co_name == 'f'
-
- def test_trace_basic(self):
- import sys
- l = []
- class Tracer:
- def __init__(self, i):
- self.i = i
- def trace(self, frame, event, arg):
- l.append((self.i, frame.f_code.co_name, event, arg))
- if frame.f_code.co_name == 'g2':
- return None # don't trace g2
- return Tracer(self.i+1).trace
- def g3(n):
- n -= 5
- return n
- def g2(n):
- n += g3(2)
- n += g3(7)
- return n
- def g(n):
- n += g2(3)
- return n
- def f(n):
- n = g(n)
- return n * 7
- sys.settrace(Tracer(0).trace)
- x = f(4)
- sys.settrace(None)
- assert x == 42
- print l
- assert l == [(0, 'f', 'call', None),
- (1, 'f', 'line', None),
- (0, 'g', 'call', None),
- (1, 'g', 'line', None),
- (0, 'g2', 'call', None),
- (0, 'g3', 'call', None),
- (1, 'g3', 'line', None),
- (2, 'g3', 'line', None),
- (3, 'g3', 'return', -3),
- (0, 'g3', 'call', None),
- (1, 'g3', 'line', None),
- (2, 'g3', 'line', None),
- (3, 'g3', 'return', 2),
- (2, 'g', 'line', None),
- (3, 'g', 'return', 6),
- (2, 'f', 'line', None),
- (3, 'f', 'return', 42)]
-
- def test_trace_exc(self):
- import sys
- l = []
- def ltrace(a,b,c):
- if b == 'exception':
- l.append(c)
- return ltrace
- def trace(a,b,c): return ltrace
- def f():
- try:
- raise Exception
- except:
- pass
- sys.settrace(trace)
- f()
- sys.settrace(None)
- assert len(l) == 1
- assert isinstance(l[0][1], Exception)
-
- def test_trace_ignore_hidden(self):
- import sys
- import _testing
-
- l = []
- def trace(a,b,c):
- l.append((a,b,c))
-
- def f():
- h = _testing.Hidden()
- r = h.meth()
- return r
-
- sys.settrace(trace)
- res = f()
- sys.settrace(None)
- assert len(l) == 1
- assert l[0][1] == 'call'
- assert res == 'hidden' # sanity
-
- def test_trace_hidden_prints(self):
- import sys
-
- l = []
- def trace(a,b,c):
- l.append((a,b,c))
- return trace
-
- outputf = open(self.tempfile1, 'w')
- def f():
- print >> outputf, 1
- print >> outputf, 2
- print >> outputf, 3
- return "that's the return value"
-
- sys.settrace(trace)
- f()
- sys.settrace(None)
- outputf.close()
- # should get 1 "call", 3 "line" and 1 "return" events, and no call
- # or return for the internal app-level implementation of 'print'
- assert len(l) == 6
- assert [what for (frame, what, arg) in l] == [
- 'call', 'line', 'line', 'line', 'line', 'return']
- assert l[-1][2] == "that's the return value"
-
- def test_trace_return_exc(self):
- import sys
- l = []
- def trace(a,b,c):
- if b in ('exception', 'return'):
- l.append((b, c))
- return trace
-
- def g():
- raise Exception
- def f():
- try:
- g()
- except:
- pass
- sys.settrace(trace)
- f()
- sys.settrace(None)
- assert len(l) == 4
- assert l[0][0] == 'exception'
- assert isinstance(l[0][1][1], Exception)
- assert l[1] == ('return', None)
- assert l[2][0] == 'exception'
- assert isinstance(l[2][1][1], Exception)
- assert l[3] == ('return', None)
-
- def test_trace_raises_on_return(self):
- import sys
- def trace(frame, event, arg):
- if event == 'return':
- raise ValueError
- else:
- return trace
-
- def f(): return 1
-
- for i in xrange(sys.getrecursionlimit() + 1):
- sys.settrace(trace)
- try:
- f()
- except ValueError:
- pass
-
- def test_trace_try_finally(self):
- import sys
- l = []
- def trace(frame, event, arg):
- if event == 'exception':
- l.append(arg)
- return trace
-
- def g():
- try:
- raise Exception
- finally:
- pass
-
- def f():
- try:
- g()
- except:
- pass
-
- sys.settrace(trace)
- f()
- sys.settrace(None)
- assert len(l) == 2
- assert issubclass(l[0][0], Exception)
- assert issubclass(l[1][0], Exception)
-
- def test_trace_raise_three_arg(self):
- import sys
- l = []
- def trace(frame, event, arg):
- if event == 'exception':
- l.append(arg)
- return trace
-
- def g():
- try:
- raise Exception
- except Exception as e:
- import sys
- raise Exception, e, sys.exc_info()[2]
-
- def f():
- try:
- g()
- except:
- pass
-
- sys.settrace(trace)
- f()
- sys.settrace(None)
- assert len(l) == 2
- assert issubclass(l[0][0], Exception)
- assert issubclass(l[1][0], Exception)
-
- def test_trace_generator_finalisation(self):
- import sys
- l = []
- got_exc = []
- def trace(frame, event, arg):
- l.append((frame.f_lineno, event))
- if event == 'exception':
- got_exc.append(arg)
- return trace
-
- d = {}
- exec """if 1:
- def g():
- try:
- yield True
- finally:
- pass
-
- def f():
- try:
- gen = g()
- gen.next()
- gen.close()
- except:
- pass
- """ in d
- f = d['f']
-
- sys.settrace(trace)
- f()
- sys.settrace(None)
- 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
- l = []
- def ltrace(a,b,c):
- if b == 'exception':
- l.append(c)
- return ltrace
- def trace(a,b,c): return ltrace
- def f():
- try:
- 1/0
- except:
- try:
- raise
- except:
- pass
- sys.settrace(trace)
- f()
- sys.settrace(None)
- assert len(l) == 1
- assert issubclass(l[0][0], Exception)
-
- def test_dont_trace_on_raise_with_tb(self):
- import sys
- l = []
- def ltrace(a,b,c):
- if b == 'exception':
- l.append(c)
- return ltrace
- def trace(a,b,c): return ltrace
- def f():
- try:
- raise Exception
- except:
- return sys.exc_info()
- def g():
- exc, val, tb = f()
- try:
- raise exc, val, tb
- except:
- pass
- sys.settrace(trace)
- g()
- sys.settrace(None)
- assert len(l) == 1
- assert isinstance(l[0][1], Exception)
-
- def test_trace_changes_locals(self):
- import sys
- def trace(frame, what, arg):
- frame.f_locals['x'] = 42
- return trace
- def f(x):
- return x
- sys.settrace(trace)
- res = f(1)
- sys.settrace(None)
- assert res == 42
-
def test_fast2locals_called_lazily(self):
import sys
class FrameHolder:
@@ -522,110 +56,3 @@
assert res == 2
if hasattr(self, "check_no_w_locals"): # not appdirect
assert self.check_no_w_locals(fh.frame)
-
- def test_set_unset_f_trace(self):
- import sys
- seen = []
- def trace1(frame, what, arg):
- seen.append((1, frame, frame.f_lineno, what, arg))
- return trace1
- def trace2(frame, what, arg):
- seen.append((2, frame, frame.f_lineno, what, arg))
- return trace2
- def set_the_trace(f):
- f.f_trace = trace1
- sys.settrace(trace2)
- len(seen) # take one line: should not be traced
- f = sys._getframe()
- set_the_trace(f)
- len(seen) # take one line: should not be traced
- len(seen) # take one line: should not be traced
- sys.settrace(None) # and this line should be the last line traced
- len(seen) # take one line
- del f.f_trace
- len(seen) # take one line
- firstline = set_the_trace.func_code.co_firstlineno
- assert seen == [(1, f, firstline + 6, 'line', None),
- (1, f, firstline + 7, 'line', None),
- (1, f, firstline + 8, 'line', None)]
-
- def test_locals2fast_freevar_bug(self):
- import sys
- def f(n):
- class A(object):
- def g(self):
- return n
- n = 42
- return A()
- res = f(10).g()
- assert res == 10
- #
- def trace(*args):
- return trace
- sys.settrace(trace)
- res = f(10).g()
- sys.settrace(None)
- assert res == 10
-
- def test_throw_trace_bug(self):
- import sys
- def f():
- yield 5
- gen = f()
- assert next(gen) == 5
- seen = []
- def trace_func(frame, event, *args):
- seen.append(event)
- return trace_func
- sys.settrace(trace_func)
- try:
- gen.throw(ValueError)
- except ValueError:
- pass
- sys.settrace(None)
- assert seen == ['call', 'exception', 'return']
-
- def test_generator_trace_stopiteration(self):
- import sys
- def f():
- yield 5
- gen = f()
- assert next(gen) == 5
- seen = []
- def trace_func(frame, event, *args):
- print('TRACE:', frame, event, args)
- seen.append(event)
- return trace_func
- def g():
- for x in gen:
- never_entered
- sys.settrace(trace_func)
- g()
- sys.settrace(None)
- print 'seen:', seen
- # on Python 3 we get an extra 'exception' when 'for' catches
- # StopIteration
- assert seen == ['call', 'line', 'call', 'return', 'return']
-
- def test_local_trace_function_returning_None_ignored(self):
- # behave the same as CPython does, and in contradiction with
- # the documentation.
- def tracer(f, event, arg):
- assert event == 'call'
- return local_tracer
-
- seen = []
- def local_tracer(f, event, arg):
- seen.append(event)
- return None # but 'local_tracer' will be called again
-
- def function():
- a = 1
- a = 2
- a = 3
-
- import sys
- sys.settrace(tracer)
- function()
- sys.settrace(None)
- assert seen == ["line", "line", "line", "return"]
More information about the pypy-commit
mailing list