##// END OF EJS Templates
Windows doesn't let you read files open for writing, I think.
Itamar Turner-Trauring -
Show More
@@ -1,274 +1,274 b''
1 1 """Tests for debugging machinery.
2 2 """
3 3
4 4 # Copyright (c) IPython Development Team.
5 5 # Distributed under the terms of the Modified BSD License.
6 6
7 7 import sys
8 8 import warnings
9 9 from tempfile import NamedTemporaryFile
10 10 from subprocess import check_output
11 11
12 12 import nose.tools as nt
13 13
14 14 from IPython.core import debugger
15 15
16 16 #-----------------------------------------------------------------------------
17 17 # Helper classes, from CPython's Pdb test suite
18 18 #-----------------------------------------------------------------------------
19 19
20 20 class _FakeInput(object):
21 21 """
22 22 A fake input stream for pdb's interactive debugger. Whenever a
23 23 line is read, print it (to simulate the user typing it), and then
24 24 return it. The set of lines to return is specified in the
25 25 constructor; they should not have trailing newlines.
26 26 """
27 27 def __init__(self, lines):
28 28 self.lines = iter(lines)
29 29
30 30 def readline(self):
31 31 line = next(self.lines)
32 32 print(line)
33 33 return line+'\n'
34 34
35 35 class PdbTestInput(object):
36 36 """Context manager that makes testing Pdb in doctests easier."""
37 37
38 38 def __init__(self, input):
39 39 self.input = input
40 40
41 41 def __enter__(self):
42 42 self.real_stdin = sys.stdin
43 43 sys.stdin = _FakeInput(self.input)
44 44
45 45 def __exit__(self, *exc):
46 46 sys.stdin = self.real_stdin
47 47
48 48 #-----------------------------------------------------------------------------
49 49 # Tests
50 50 #-----------------------------------------------------------------------------
51 51
52 52 def test_longer_repr():
53 53 from reprlib import repr as trepr
54 54
55 55 a = '1234567890'* 7
56 56 ar = "'1234567890123456789012345678901234567890123456789012345678901234567890'"
57 57 a_trunc = "'123456789012...8901234567890'"
58 58 nt.assert_equal(trepr(a), a_trunc)
59 59 # The creation of our tracer modifies the repr module's repr function
60 60 # in-place, since that global is used directly by the stdlib's pdb module.
61 61 with warnings.catch_warnings():
62 62 warnings.simplefilter('ignore', DeprecationWarning)
63 63 debugger.Tracer()
64 64 nt.assert_equal(trepr(a), ar)
65 65
66 66 def test_ipdb_magics():
67 67 '''Test calling some IPython magics from ipdb.
68 68
69 69 First, set up some test functions and classes which we can inspect.
70 70
71 71 >>> class ExampleClass(object):
72 72 ... """Docstring for ExampleClass."""
73 73 ... def __init__(self):
74 74 ... """Docstring for ExampleClass.__init__"""
75 75 ... pass
76 76 ... def __str__(self):
77 77 ... return "ExampleClass()"
78 78
79 79 >>> def example_function(x, y, z="hello"):
80 80 ... """Docstring for example_function."""
81 81 ... pass
82 82
83 83 >>> old_trace = sys.gettrace()
84 84
85 85 Create a function which triggers ipdb.
86 86
87 87 >>> def trigger_ipdb():
88 88 ... a = ExampleClass()
89 89 ... debugger.Pdb().set_trace()
90 90
91 91 >>> with PdbTestInput([
92 92 ... 'pdef example_function',
93 93 ... 'pdoc ExampleClass',
94 94 ... 'up',
95 95 ... 'down',
96 96 ... 'list',
97 97 ... 'pinfo a',
98 98 ... 'll',
99 99 ... 'continue',
100 100 ... ]):
101 101 ... trigger_ipdb()
102 102 --Return--
103 103 None
104 104 > <doctest ...>(3)trigger_ipdb()
105 105 1 def trigger_ipdb():
106 106 2 a = ExampleClass()
107 107 ----> 3 debugger.Pdb().set_trace()
108 108 <BLANKLINE>
109 109 ipdb> pdef example_function
110 110 example_function(x, y, z='hello')
111 111 ipdb> pdoc ExampleClass
112 112 Class docstring:
113 113 Docstring for ExampleClass.
114 114 Init docstring:
115 115 Docstring for ExampleClass.__init__
116 116 ipdb> up
117 117 > <doctest ...>(11)<module>()
118 118 7 'pinfo a',
119 119 8 'll',
120 120 9 'continue',
121 121 10 ]):
122 122 ---> 11 trigger_ipdb()
123 123 <BLANKLINE>
124 124 ipdb> down
125 125 None
126 126 > <doctest ...>(3)trigger_ipdb()
127 127 1 def trigger_ipdb():
128 128 2 a = ExampleClass()
129 129 ----> 3 debugger.Pdb().set_trace()
130 130 <BLANKLINE>
131 131 ipdb> list
132 132 1 def trigger_ipdb():
133 133 2 a = ExampleClass()
134 134 ----> 3 debugger.Pdb().set_trace()
135 135 <BLANKLINE>
136 136 ipdb> pinfo a
137 137 Type: ExampleClass
138 138 String form: ExampleClass()
139 139 Namespace: Local...
140 140 Docstring: Docstring for ExampleClass.
141 141 Init docstring: Docstring for ExampleClass.__init__
142 142 ipdb> ll
143 143 1 def trigger_ipdb():
144 144 2 a = ExampleClass()
145 145 ----> 3 debugger.Pdb().set_trace()
146 146 <BLANKLINE>
147 147 ipdb> continue
148 148
149 149 Restore previous trace function, e.g. for coverage.py
150 150
151 151 >>> sys.settrace(old_trace)
152 152 '''
153 153
154 154 def test_ipdb_magics2():
155 155 '''Test ipdb with a very short function.
156 156
157 157 >>> old_trace = sys.gettrace()
158 158
159 159 >>> def bar():
160 160 ... pass
161 161
162 162 Run ipdb.
163 163
164 164 >>> with PdbTestInput([
165 165 ... 'continue',
166 166 ... ]):
167 167 ... debugger.Pdb().runcall(bar)
168 168 > <doctest ...>(2)bar()
169 169 1 def bar():
170 170 ----> 2 pass
171 171 <BLANKLINE>
172 172 ipdb> continue
173 173
174 174 Restore previous trace function, e.g. for coverage.py
175 175
176 176 >>> sys.settrace(old_trace)
177 177 '''
178 178
179 179 def can_quit():
180 180 '''Test that quit work in ipydb
181 181
182 182 >>> old_trace = sys.gettrace()
183 183
184 184 >>> def bar():
185 185 ... pass
186 186
187 187 >>> with PdbTestInput([
188 188 ... 'quit',
189 189 ... ]):
190 190 ... debugger.Pdb().runcall(bar)
191 191 > <doctest ...>(2)bar()
192 192 1 def bar():
193 193 ----> 2 pass
194 194 <BLANKLINE>
195 195 ipdb> quit
196 196
197 197 Restore previous trace function, e.g. for coverage.py
198 198
199 199 >>> sys.settrace(old_trace)
200 200 '''
201 201
202 202
203 203 def can_exit():
204 204 '''Test that quit work in ipydb
205 205
206 206 >>> old_trace = sys.gettrace()
207 207
208 208 >>> def bar():
209 209 ... pass
210 210
211 211 >>> with PdbTestInput([
212 212 ... 'exit',
213 213 ... ]):
214 214 ... debugger.Pdb().runcall(bar)
215 215 > <doctest ...>(2)bar()
216 216 1 def bar():
217 217 ----> 2 pass
218 218 <BLANKLINE>
219 219 ipdb> exit
220 220
221 221 Restore previous trace function, e.g. for coverage.py
222 222
223 223 >>> sys.settrace(old_trace)
224 224 '''
225 225
226 226
227 227 interruptible_debugger = """\
228 228 import threading
229 229 import time
230 230 from os import _exit
231 231 from bdb import BdbQuit
232 232
233 233 from IPython.core.debugger import set_trace
234 234
235 235 def interrupt():
236 236 time.sleep(0.1)
237 237 import os, signal
238 238 os.kill(os.getpid(), signal.SIGINT)
239 239 threading.Thread(target=interrupt).start()
240 240
241 241 # Timeout if the interrupt doesn't happen:
242 242 def interrupt():
243 243 try:
244 244 time.sleep(2)
245 245 except KeyboardInterrupt:
246 246 return
247 247 _exit(7)
248 248 threading.Thread(target=interrupt, daemon=True).start()
249 249
250 250 def main():
251 251 set_trace()
252 252
253 253 if __name__ == '__main__':
254 254 try:
255 255 #print("Starting debugger...")
256 256 main()
257 257 print("Debugger exited without error.")
258 258 except (KeyboardInterrupt, BdbQuit):
259 259 print("Caught KeyboardInterrupt or BdbQuit, PASSED")
260 260 except Exception as e:
261 261 print("Got wrong exception...")
262 262 raise e
263 263 """
264 264
265 265
266 266 def test_interruptible_core_debugger():
267 267 """The debugger can be interrupted."""
268 with NamedTemporaryFile("w") as f:
268 with NamedTemporaryFile("w", delete=False) as f:
269 269 f.write(interruptible_debugger)
270 270 f.flush()
271 result = check_output([sys.executable, f.name],
272 encoding=sys.getdefaultencoding())
273 # Wait for it to start:
274 assert "PASSED" in result
271 result = check_output([sys.executable, f.name],
272 encoding=sys.getdefaultencoding())
273 # Wait for it to start:
274 assert "PASSED" in result
General Comments 0
You need to be logged in to leave comments. Login now