File: test_pyframe.py

package info (click to toggle)
pypy3 7.3.19%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 212,236 kB
  • sloc: python: 2,098,316; ansic: 540,565; sh: 21,462; asm: 14,419; cpp: 4,451; makefile: 4,209; objc: 761; xml: 530; exp: 499; javascript: 314; pascal: 244; lisp: 45; csh: 12; awk: 4
file content (160 lines) | stat: -rw-r--r-- 5,164 bytes parent folder | download | duplicates (2)
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