1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
|
from pypy.conftest import option
from pypy.interpreter.gateway import interp2app
def check_no_w_locals(space, w_frame):
return space.wrap(w_frame.getorcreatedebug().w_locals is None)
class AppTestPyFrame:
def setup_class(cls):
space = cls.space
if not option.runappdirect:
w_call_further = cls.space.appexec([], """():
def call_further(f):
return f()
return call_further
""")
assert not w_call_further.code.hidden_applevel
w_call_further.code.hidden_applevel = True # hack
cls.w_call_further = w_call_further
cls.w_check_no_w_locals = space.wrap(interp2app(check_no_w_locals))
# test for the presence of the attributes, not functionality
def test_set_lineno(self):
import sys
class JumpTracer:
def __init__(self, function):
self.function = function
self.jumpFrom = function.jump[0]
self.jumpTo = function.jump[1]
self.done = False
def trace(self, frame, event, arg):
if not self.done and frame.f_code == self.function.__code__:
firstLine = frame.f_code.co_firstlineno
if event == 'line' and frame.f_lineno == firstLine + self.jumpFrom:
# Cope with non-integer self.jumpTo (because of
# no_jump_to_non_integers below).
try:
frame.f_lineno = firstLine + self.jumpTo
except TypeError:
frame.f_lineno = self.jumpTo
self.done = True
return self.trace
def run_test(func):
tracer = JumpTracer(func)
sys.settrace(tracer.trace)
output = []
func(output)
sys.settrace(None)
assert func.output == output
# copied from cpython test suite
def jump_out_of_block_forwards(output):
for i in 1, 2:
output.append(2)
for j in [3]: # Also tests jumping over a block
output.append(4)
output.append(5)
jump_out_of_block_forwards.jump = (3, 5)
jump_out_of_block_forwards.output = [2, 5]
run_test(jump_out_of_block_forwards)
def jump_out_of_block_backwards(output):
output.append(1)
for i in [1]:
output.append(3)
for j in [2]: # Also tests jumping over a block
output.append(5)
output.append(6)
output.append(7)
jump_out_of_block_backwards.jump = (6, 1)
jump_out_of_block_backwards.output = [1, 3, 5, 1, 3, 5, 6, 7]
run_test(jump_out_of_block_backwards)
def jump_to_codeless_line(output):
output.append(1)
# Jumping to this line should skip to the next one.
output.append(3)
jump_to_codeless_line.jump = (1, 2)
jump_to_codeless_line.output = [3]
run_test(jump_to_codeless_line)
def jump_in_nested_finally(output):
try:
output.append(2)
finally:
output.append(4)
try:
output.append(6)
finally:
output.append(8)
output.append(9)
jump_in_nested_finally.jump = (4, 9)
jump_in_nested_finally.output = [2, 9]
run_test(jump_in_nested_finally)
def test_f_back_hidden(self):
if not hasattr(self, 'call_further'):
skip("not for runappdirect testing")
import sys
def f():
return (sys._getframe(0),
sys._getframe(1),
sys._getframe(0).f_back)
def main():
return self.call_further(f)
f0, f1, f1bis = main()
assert f0.f_code.co_name == 'f'
assert f1.f_code.co_name == 'main'
assert f1bis is f1
assert f0.f_back is f1
def test_fast2locals_called_lazily(self):
import sys
class FrameHolder:
pass
fh = FrameHolder()
def trace(frame, what, arg):
# trivial trace function, does not access f_locals
fh.frame = frame
return trace
def f(x):
x += 1
return x
sys.settrace(trace)
res = f(1)
sys.settrace(None)
assert res == 2
if hasattr(self, "check_no_w_locals"): # not appdirect
assert self.check_no_w_locals(fh.frame)
def test_del_cell_locals_bug(self):
"""
def f():
x = object()
def foo():
print(x)
locals()
del x
assert "x" not in locals()
f()
"""
def test_repr(self):
import sys
def a_name(a, b, c):
a + b + c
return sys._getframe()
frame = a_name(5, 6, 4)
r = repr(frame)
assert "a_name" in r
|