##// END OF EJS Templates
[core][tests][debugger] Remove nose
Samuel Gaist -
Show More
@@ -1,576 +1,574 b''
1 """Tests for debugging machinery.
1 """Tests for debugging machinery.
2 """
2 """
3
3
4 # Copyright (c) IPython Development Team.
4 # Copyright (c) IPython Development Team.
5 # Distributed under the terms of the Modified BSD License.
5 # Distributed under the terms of the Modified BSD License.
6
6
7 import bdb
7 import bdb
8 import builtins
8 import builtins
9 import os
9 import os
10 import signal
10 import signal
11 import subprocess
11 import subprocess
12 import sys
12 import sys
13 import time
13 import time
14 import warnings
14 import warnings
15
15
16 from subprocess import PIPE, CalledProcessError, check_output
16 from subprocess import PIPE, CalledProcessError, check_output
17 from tempfile import NamedTemporaryFile
17 from tempfile import NamedTemporaryFile
18 from textwrap import dedent
18 from textwrap import dedent
19 from unittest.mock import patch
19 from unittest.mock import patch
20
20
21 import nose.tools as nt
22
23 from IPython.core import debugger
21 from IPython.core import debugger
24 from IPython.testing import IPYTHON_TESTING_TIMEOUT_SCALE
22 from IPython.testing import IPYTHON_TESTING_TIMEOUT_SCALE
25 from IPython.testing.decorators import skip_win32
23 from IPython.testing.decorators import skip_win32
26
24
27 #-----------------------------------------------------------------------------
25 #-----------------------------------------------------------------------------
28 # Helper classes, from CPython's Pdb test suite
26 # Helper classes, from CPython's Pdb test suite
29 #-----------------------------------------------------------------------------
27 #-----------------------------------------------------------------------------
30
28
31 class _FakeInput(object):
29 class _FakeInput(object):
32 """
30 """
33 A fake input stream for pdb's interactive debugger. Whenever a
31 A fake input stream for pdb's interactive debugger. Whenever a
34 line is read, print it (to simulate the user typing it), and then
32 line is read, print it (to simulate the user typing it), and then
35 return it. The set of lines to return is specified in the
33 return it. The set of lines to return is specified in the
36 constructor; they should not have trailing newlines.
34 constructor; they should not have trailing newlines.
37 """
35 """
38 def __init__(self, lines):
36 def __init__(self, lines):
39 self.lines = iter(lines)
37 self.lines = iter(lines)
40
38
41 def readline(self):
39 def readline(self):
42 line = next(self.lines)
40 line = next(self.lines)
43 print(line)
41 print(line)
44 return line+'\n'
42 return line+'\n'
45
43
46 class PdbTestInput(object):
44 class PdbTestInput(object):
47 """Context manager that makes testing Pdb in doctests easier."""
45 """Context manager that makes testing Pdb in doctests easier."""
48
46
49 def __init__(self, input):
47 def __init__(self, input):
50 self.input = input
48 self.input = input
51
49
52 def __enter__(self):
50 def __enter__(self):
53 self.real_stdin = sys.stdin
51 self.real_stdin = sys.stdin
54 sys.stdin = _FakeInput(self.input)
52 sys.stdin = _FakeInput(self.input)
55
53
56 def __exit__(self, *exc):
54 def __exit__(self, *exc):
57 sys.stdin = self.real_stdin
55 sys.stdin = self.real_stdin
58
56
59 #-----------------------------------------------------------------------------
57 #-----------------------------------------------------------------------------
60 # Tests
58 # Tests
61 #-----------------------------------------------------------------------------
59 #-----------------------------------------------------------------------------
62
60
63 def test_longer_repr():
61 def test_longer_repr():
64 from reprlib import repr as trepr
62 from reprlib import repr as trepr
65
63
66 a = '1234567890'* 7
64 a = '1234567890'* 7
67 ar = "'1234567890123456789012345678901234567890123456789012345678901234567890'"
65 ar = "'1234567890123456789012345678901234567890123456789012345678901234567890'"
68 a_trunc = "'123456789012...8901234567890'"
66 a_trunc = "'123456789012...8901234567890'"
69 nt.assert_equal(trepr(a), a_trunc)
67 assert trepr(a) == a_trunc
70 # The creation of our tracer modifies the repr module's repr function
68 # The creation of our tracer modifies the repr module's repr function
71 # in-place, since that global is used directly by the stdlib's pdb module.
69 # in-place, since that global is used directly by the stdlib's pdb module.
72 with warnings.catch_warnings():
70 with warnings.catch_warnings():
73 warnings.simplefilter('ignore', DeprecationWarning)
71 warnings.simplefilter('ignore', DeprecationWarning)
74 debugger.Tracer()
72 debugger.Tracer()
75 nt.assert_equal(trepr(a), ar)
73 assert trepr(a) == ar
76
74
77 def test_ipdb_magics():
75 def test_ipdb_magics():
78 '''Test calling some IPython magics from ipdb.
76 '''Test calling some IPython magics from ipdb.
79
77
80 First, set up some test functions and classes which we can inspect.
78 First, set up some test functions and classes which we can inspect.
81
79
82 >>> class ExampleClass(object):
80 >>> class ExampleClass(object):
83 ... """Docstring for ExampleClass."""
81 ... """Docstring for ExampleClass."""
84 ... def __init__(self):
82 ... def __init__(self):
85 ... """Docstring for ExampleClass.__init__"""
83 ... """Docstring for ExampleClass.__init__"""
86 ... pass
84 ... pass
87 ... def __str__(self):
85 ... def __str__(self):
88 ... return "ExampleClass()"
86 ... return "ExampleClass()"
89
87
90 >>> def example_function(x, y, z="hello"):
88 >>> def example_function(x, y, z="hello"):
91 ... """Docstring for example_function."""
89 ... """Docstring for example_function."""
92 ... pass
90 ... pass
93
91
94 >>> old_trace = sys.gettrace()
92 >>> old_trace = sys.gettrace()
95
93
96 Create a function which triggers ipdb.
94 Create a function which triggers ipdb.
97
95
98 >>> def trigger_ipdb():
96 >>> def trigger_ipdb():
99 ... a = ExampleClass()
97 ... a = ExampleClass()
100 ... debugger.Pdb().set_trace()
98 ... debugger.Pdb().set_trace()
101
99
102 >>> with PdbTestInput([
100 >>> with PdbTestInput([
103 ... 'pdef example_function',
101 ... 'pdef example_function',
104 ... 'pdoc ExampleClass',
102 ... 'pdoc ExampleClass',
105 ... 'up',
103 ... 'up',
106 ... 'down',
104 ... 'down',
107 ... 'list',
105 ... 'list',
108 ... 'pinfo a',
106 ... 'pinfo a',
109 ... 'll',
107 ... 'll',
110 ... 'continue',
108 ... 'continue',
111 ... ]):
109 ... ]):
112 ... trigger_ipdb()
110 ... trigger_ipdb()
113 --Return--
111 --Return--
114 None
112 None
115 > <doctest ...>(3)trigger_ipdb()
113 > <doctest ...>(3)trigger_ipdb()
116 1 def trigger_ipdb():
114 1 def trigger_ipdb():
117 2 a = ExampleClass()
115 2 a = ExampleClass()
118 ----> 3 debugger.Pdb().set_trace()
116 ----> 3 debugger.Pdb().set_trace()
119 <BLANKLINE>
117 <BLANKLINE>
120 ipdb> pdef example_function
118 ipdb> pdef example_function
121 example_function(x, y, z='hello')
119 example_function(x, y, z='hello')
122 ipdb> pdoc ExampleClass
120 ipdb> pdoc ExampleClass
123 Class docstring:
121 Class docstring:
124 Docstring for ExampleClass.
122 Docstring for ExampleClass.
125 Init docstring:
123 Init docstring:
126 Docstring for ExampleClass.__init__
124 Docstring for ExampleClass.__init__
127 ipdb> up
125 ipdb> up
128 > <doctest ...>(11)<module>()
126 > <doctest ...>(11)<module>()
129 7 'pinfo a',
127 7 'pinfo a',
130 8 'll',
128 8 'll',
131 9 'continue',
129 9 'continue',
132 10 ]):
130 10 ]):
133 ---> 11 trigger_ipdb()
131 ---> 11 trigger_ipdb()
134 <BLANKLINE>
132 <BLANKLINE>
135 ipdb> down
133 ipdb> down
136 None
134 None
137 > <doctest ...>(3)trigger_ipdb()
135 > <doctest ...>(3)trigger_ipdb()
138 1 def trigger_ipdb():
136 1 def trigger_ipdb():
139 2 a = ExampleClass()
137 2 a = ExampleClass()
140 ----> 3 debugger.Pdb().set_trace()
138 ----> 3 debugger.Pdb().set_trace()
141 <BLANKLINE>
139 <BLANKLINE>
142 ipdb> list
140 ipdb> list
143 1 def trigger_ipdb():
141 1 def trigger_ipdb():
144 2 a = ExampleClass()
142 2 a = ExampleClass()
145 ----> 3 debugger.Pdb().set_trace()
143 ----> 3 debugger.Pdb().set_trace()
146 <BLANKLINE>
144 <BLANKLINE>
147 ipdb> pinfo a
145 ipdb> pinfo a
148 Type: ExampleClass
146 Type: ExampleClass
149 String form: ExampleClass()
147 String form: ExampleClass()
150 Namespace: Local...
148 Namespace: Local...
151 Docstring: Docstring for ExampleClass.
149 Docstring: Docstring for ExampleClass.
152 Init docstring: Docstring for ExampleClass.__init__
150 Init docstring: Docstring for ExampleClass.__init__
153 ipdb> ll
151 ipdb> ll
154 1 def trigger_ipdb():
152 1 def trigger_ipdb():
155 2 a = ExampleClass()
153 2 a = ExampleClass()
156 ----> 3 debugger.Pdb().set_trace()
154 ----> 3 debugger.Pdb().set_trace()
157 <BLANKLINE>
155 <BLANKLINE>
158 ipdb> continue
156 ipdb> continue
159
157
160 Restore previous trace function, e.g. for coverage.py
158 Restore previous trace function, e.g. for coverage.py
161
159
162 >>> sys.settrace(old_trace)
160 >>> sys.settrace(old_trace)
163 '''
161 '''
164
162
165 def test_ipdb_magics2():
163 def test_ipdb_magics2():
166 '''Test ipdb with a very short function.
164 '''Test ipdb with a very short function.
167
165
168 >>> old_trace = sys.gettrace()
166 >>> old_trace = sys.gettrace()
169
167
170 >>> def bar():
168 >>> def bar():
171 ... pass
169 ... pass
172
170
173 Run ipdb.
171 Run ipdb.
174
172
175 >>> with PdbTestInput([
173 >>> with PdbTestInput([
176 ... 'continue',
174 ... 'continue',
177 ... ]):
175 ... ]):
178 ... debugger.Pdb().runcall(bar)
176 ... debugger.Pdb().runcall(bar)
179 > <doctest ...>(2)bar()
177 > <doctest ...>(2)bar()
180 1 def bar():
178 1 def bar():
181 ----> 2 pass
179 ----> 2 pass
182 <BLANKLINE>
180 <BLANKLINE>
183 ipdb> continue
181 ipdb> continue
184
182
185 Restore previous trace function, e.g. for coverage.py
183 Restore previous trace function, e.g. for coverage.py
186
184
187 >>> sys.settrace(old_trace)
185 >>> sys.settrace(old_trace)
188 '''
186 '''
189
187
190 def can_quit():
188 def can_quit():
191 '''Test that quit work in ipydb
189 '''Test that quit work in ipydb
192
190
193 >>> old_trace = sys.gettrace()
191 >>> old_trace = sys.gettrace()
194
192
195 >>> def bar():
193 >>> def bar():
196 ... pass
194 ... pass
197
195
198 >>> with PdbTestInput([
196 >>> with PdbTestInput([
199 ... 'quit',
197 ... 'quit',
200 ... ]):
198 ... ]):
201 ... debugger.Pdb().runcall(bar)
199 ... debugger.Pdb().runcall(bar)
202 > <doctest ...>(2)bar()
200 > <doctest ...>(2)bar()
203 1 def bar():
201 1 def bar():
204 ----> 2 pass
202 ----> 2 pass
205 <BLANKLINE>
203 <BLANKLINE>
206 ipdb> quit
204 ipdb> quit
207
205
208 Restore previous trace function, e.g. for coverage.py
206 Restore previous trace function, e.g. for coverage.py
209
207
210 >>> sys.settrace(old_trace)
208 >>> sys.settrace(old_trace)
211 '''
209 '''
212
210
213
211
214 def can_exit():
212 def can_exit():
215 '''Test that quit work in ipydb
213 '''Test that quit work in ipydb
216
214
217 >>> old_trace = sys.gettrace()
215 >>> old_trace = sys.gettrace()
218
216
219 >>> def bar():
217 >>> def bar():
220 ... pass
218 ... pass
221
219
222 >>> with PdbTestInput([
220 >>> with PdbTestInput([
223 ... 'exit',
221 ... 'exit',
224 ... ]):
222 ... ]):
225 ... debugger.Pdb().runcall(bar)
223 ... debugger.Pdb().runcall(bar)
226 > <doctest ...>(2)bar()
224 > <doctest ...>(2)bar()
227 1 def bar():
225 1 def bar():
228 ----> 2 pass
226 ----> 2 pass
229 <BLANKLINE>
227 <BLANKLINE>
230 ipdb> exit
228 ipdb> exit
231
229
232 Restore previous trace function, e.g. for coverage.py
230 Restore previous trace function, e.g. for coverage.py
233
231
234 >>> sys.settrace(old_trace)
232 >>> sys.settrace(old_trace)
235 '''
233 '''
236
234
237
235
238 def test_interruptible_core_debugger():
236 def test_interruptible_core_debugger():
239 """The debugger can be interrupted.
237 """The debugger can be interrupted.
240
238
241 The presumption is there is some mechanism that causes a KeyboardInterrupt
239 The presumption is there is some mechanism that causes a KeyboardInterrupt
242 (this is implemented in ipykernel). We want to ensure the
240 (this is implemented in ipykernel). We want to ensure the
243 KeyboardInterrupt cause debugging to cease.
241 KeyboardInterrupt cause debugging to cease.
244 """
242 """
245 def raising_input(msg="", called=[0]):
243 def raising_input(msg="", called=[0]):
246 called[0] += 1
244 called[0] += 1
247 if called[0] == 1:
245 if called[0] == 1:
248 raise KeyboardInterrupt()
246 raise KeyboardInterrupt()
249 else:
247 else:
250 raise AssertionError("input() should only be called once!")
248 raise AssertionError("input() should only be called once!")
251
249
252 with patch.object(builtins, "input", raising_input):
250 with patch.object(builtins, "input", raising_input):
253 debugger.InterruptiblePdb().set_trace()
251 debugger.InterruptiblePdb().set_trace()
254 # The way this test will fail is by set_trace() never exiting,
252 # The way this test will fail is by set_trace() never exiting,
255 # resulting in a timeout by the test runner. The alternative
253 # resulting in a timeout by the test runner. The alternative
256 # implementation would involve a subprocess, but that adds issues with
254 # implementation would involve a subprocess, but that adds issues with
257 # interrupting subprocesses that are rather complex, so it's simpler
255 # interrupting subprocesses that are rather complex, so it's simpler
258 # just to do it this way.
256 # just to do it this way.
259
257
260 @skip_win32
258 @skip_win32
261 def test_xmode_skip():
259 def test_xmode_skip():
262 """that xmode skip frames
260 """that xmode skip frames
263
261
264 Not as a doctest as pytest does not run doctests.
262 Not as a doctest as pytest does not run doctests.
265 """
263 """
266 import pexpect
264 import pexpect
267 env = os.environ.copy()
265 env = os.environ.copy()
268 env["IPY_TEST_SIMPLE_PROMPT"] = "1"
266 env["IPY_TEST_SIMPLE_PROMPT"] = "1"
269
267
270 child = pexpect.spawn(
268 child = pexpect.spawn(
271 sys.executable, ["-m", "IPython", "--colors=nocolor"], env=env
269 sys.executable, ["-m", "IPython", "--colors=nocolor"], env=env
272 )
270 )
273 child.timeout = 15 * IPYTHON_TESTING_TIMEOUT_SCALE
271 child.timeout = 15 * IPYTHON_TESTING_TIMEOUT_SCALE
274
272
275 child.expect("IPython")
273 child.expect("IPython")
276 child.expect("\n")
274 child.expect("\n")
277 child.expect_exact("In [1]")
275 child.expect_exact("In [1]")
278
276
279 block = dedent(
277 block = dedent(
280 """
278 """
281 def f():
279 def f():
282 __tracebackhide__ = True
280 __tracebackhide__ = True
283 g()
281 g()
284
282
285 def g():
283 def g():
286 raise ValueError
284 raise ValueError
287
285
288 f()
286 f()
289 """
287 """
290 )
288 )
291
289
292 for line in block.splitlines():
290 for line in block.splitlines():
293 child.sendline(line)
291 child.sendline(line)
294 child.expect_exact(line)
292 child.expect_exact(line)
295 child.expect_exact("skipping")
293 child.expect_exact("skipping")
296
294
297 block = dedent(
295 block = dedent(
298 """
296 """
299 def f():
297 def f():
300 __tracebackhide__ = True
298 __tracebackhide__ = True
301 g()
299 g()
302
300
303 def g():
301 def g():
304 from IPython.core.debugger import set_trace
302 from IPython.core.debugger import set_trace
305 set_trace()
303 set_trace()
306
304
307 f()
305 f()
308 """
306 """
309 )
307 )
310
308
311 for line in block.splitlines():
309 for line in block.splitlines():
312 child.sendline(line)
310 child.sendline(line)
313 child.expect_exact(line)
311 child.expect_exact(line)
314
312
315 child.expect("ipdb>")
313 child.expect("ipdb>")
316 child.sendline("w")
314 child.sendline("w")
317 child.expect("hidden")
315 child.expect("hidden")
318 child.expect("ipdb>")
316 child.expect("ipdb>")
319 child.sendline("skip_hidden false")
317 child.sendline("skip_hidden false")
320 child.sendline("w")
318 child.sendline("w")
321 child.expect("__traceba")
319 child.expect("__traceba")
322 child.expect("ipdb>")
320 child.expect("ipdb>")
323
321
324 child.close()
322 child.close()
325
323
326
324
327 skip_decorators_blocks = (
325 skip_decorators_blocks = (
328 """
326 """
329 def helpers_helper():
327 def helpers_helper():
330 pass # should not stop here except breakpoint
328 pass # should not stop here except breakpoint
331 """,
329 """,
332 """
330 """
333 def helper_1():
331 def helper_1():
334 helpers_helper() # should not stop here
332 helpers_helper() # should not stop here
335 """,
333 """,
336 """
334 """
337 def helper_2():
335 def helper_2():
338 pass # should not stop here
336 pass # should not stop here
339 """,
337 """,
340 """
338 """
341 def pdb_skipped_decorator2(function):
339 def pdb_skipped_decorator2(function):
342 def wrapped_fn(*args, **kwargs):
340 def wrapped_fn(*args, **kwargs):
343 __debuggerskip__ = True
341 __debuggerskip__ = True
344 helper_2()
342 helper_2()
345 __debuggerskip__ = False
343 __debuggerskip__ = False
346 result = function(*args, **kwargs)
344 result = function(*args, **kwargs)
347 __debuggerskip__ = True
345 __debuggerskip__ = True
348 helper_2()
346 helper_2()
349 return result
347 return result
350 return wrapped_fn
348 return wrapped_fn
351 """,
349 """,
352 """
350 """
353 def pdb_skipped_decorator(function):
351 def pdb_skipped_decorator(function):
354 def wrapped_fn(*args, **kwargs):
352 def wrapped_fn(*args, **kwargs):
355 __debuggerskip__ = True
353 __debuggerskip__ = True
356 helper_1()
354 helper_1()
357 __debuggerskip__ = False
355 __debuggerskip__ = False
358 result = function(*args, **kwargs)
356 result = function(*args, **kwargs)
359 __debuggerskip__ = True
357 __debuggerskip__ = True
360 helper_2()
358 helper_2()
361 return result
359 return result
362 return wrapped_fn
360 return wrapped_fn
363 """,
361 """,
364 """
362 """
365 @pdb_skipped_decorator
363 @pdb_skipped_decorator
366 @pdb_skipped_decorator2
364 @pdb_skipped_decorator2
367 def bar(x, y):
365 def bar(x, y):
368 return x * y
366 return x * y
369 """,
367 """,
370 """import IPython.terminal.debugger as ipdb""",
368 """import IPython.terminal.debugger as ipdb""",
371 """
369 """
372 def f():
370 def f():
373 ipdb.set_trace()
371 ipdb.set_trace()
374 bar(3, 4)
372 bar(3, 4)
375 """,
373 """,
376 """
374 """
377 f()
375 f()
378 """,
376 """,
379 )
377 )
380
378
381
379
382 def _decorator_skip_setup():
380 def _decorator_skip_setup():
383 import pexpect
381 import pexpect
384
382
385 env = os.environ.copy()
383 env = os.environ.copy()
386 env["IPY_TEST_SIMPLE_PROMPT"] = "1"
384 env["IPY_TEST_SIMPLE_PROMPT"] = "1"
387
385
388 child = pexpect.spawn(
386 child = pexpect.spawn(
389 sys.executable, ["-m", "IPython", "--colors=nocolor"], env=env
387 sys.executable, ["-m", "IPython", "--colors=nocolor"], env=env
390 )
388 )
391 child.timeout = 5 * IPYTHON_TESTING_TIMEOUT_SCALE
389 child.timeout = 5 * IPYTHON_TESTING_TIMEOUT_SCALE
392
390
393 child.expect("IPython")
391 child.expect("IPython")
394 child.expect("\n")
392 child.expect("\n")
395
393
396 dedented_blocks = [dedent(b).strip() for b in skip_decorators_blocks]
394 dedented_blocks = [dedent(b).strip() for b in skip_decorators_blocks]
397 in_prompt_number = 1
395 in_prompt_number = 1
398 for cblock in dedented_blocks:
396 for cblock in dedented_blocks:
399 child.expect_exact(f"In [{in_prompt_number}]:")
397 child.expect_exact(f"In [{in_prompt_number}]:")
400 in_prompt_number += 1
398 in_prompt_number += 1
401 for line in cblock.splitlines():
399 for line in cblock.splitlines():
402 child.sendline(line)
400 child.sendline(line)
403 child.expect_exact(line)
401 child.expect_exact(line)
404 child.sendline("")
402 child.sendline("")
405 return child
403 return child
406
404
407
405
408 @skip_win32
406 @skip_win32
409 def test_decorator_skip():
407 def test_decorator_skip():
410 """test that decorator frames can be skipped."""
408 """test that decorator frames can be skipped."""
411
409
412 child = _decorator_skip_setup()
410 child = _decorator_skip_setup()
413
411
414 child.expect_exact("3 bar(3, 4)")
412 child.expect_exact("3 bar(3, 4)")
415 child.expect("ipdb>")
413 child.expect("ipdb>")
416
414
417 child.expect("ipdb>")
415 child.expect("ipdb>")
418 child.sendline("step")
416 child.sendline("step")
419 child.expect_exact("step")
417 child.expect_exact("step")
420
418
421 child.expect_exact("1 @pdb_skipped_decorator")
419 child.expect_exact("1 @pdb_skipped_decorator")
422
420
423 child.sendline("s")
421 child.sendline("s")
424 child.expect_exact("return x * y")
422 child.expect_exact("return x * y")
425
423
426 child.close()
424 child.close()
427
425
428
426
429 @skip_win32
427 @skip_win32
430 def test_decorator_skip_disabled():
428 def test_decorator_skip_disabled():
431 """test that decorator frame skipping can be disabled"""
429 """test that decorator frame skipping can be disabled"""
432
430
433 child = _decorator_skip_setup()
431 child = _decorator_skip_setup()
434
432
435 child.expect_exact("3 bar(3, 4)")
433 child.expect_exact("3 bar(3, 4)")
436
434
437 for input_, expected in [
435 for input_, expected in [
438 ("skip_predicates debuggerskip False", ""),
436 ("skip_predicates debuggerskip False", ""),
439 ("skip_predicates", "debuggerskip : False"),
437 ("skip_predicates", "debuggerskip : False"),
440 ("step", "---> 2 def wrapped_fn"),
438 ("step", "---> 2 def wrapped_fn"),
441 ("step", "----> 3 __debuggerskip__"),
439 ("step", "----> 3 __debuggerskip__"),
442 ("step", "----> 4 helper_1()"),
440 ("step", "----> 4 helper_1()"),
443 ("step", "---> 1 def helper_1():"),
441 ("step", "---> 1 def helper_1():"),
444 ("next", "----> 2 helpers_helper()"),
442 ("next", "----> 2 helpers_helper()"),
445 ("next", "--Return--"),
443 ("next", "--Return--"),
446 ("next", "----> 5 __debuggerskip__ = False"),
444 ("next", "----> 5 __debuggerskip__ = False"),
447 ]:
445 ]:
448 child.expect("ipdb>")
446 child.expect("ipdb>")
449 child.sendline(input_)
447 child.sendline(input_)
450 child.expect_exact(input_)
448 child.expect_exact(input_)
451 child.expect_exact(expected)
449 child.expect_exact(expected)
452
450
453 child.close()
451 child.close()
454
452
455
453
456 @skip_win32
454 @skip_win32
457 def test_decorator_skip_with_breakpoint():
455 def test_decorator_skip_with_breakpoint():
458 """test that decorator frame skipping can be disabled"""
456 """test that decorator frame skipping can be disabled"""
459
457
460 import pexpect
458 import pexpect
461
459
462 env = os.environ.copy()
460 env = os.environ.copy()
463 env["IPY_TEST_SIMPLE_PROMPT"] = "1"
461 env["IPY_TEST_SIMPLE_PROMPT"] = "1"
464
462
465 child = pexpect.spawn(
463 child = pexpect.spawn(
466 sys.executable, ["-m", "IPython", "--colors=nocolor"], env=env
464 sys.executable, ["-m", "IPython", "--colors=nocolor"], env=env
467 )
465 )
468 child.timeout = 5 * IPYTHON_TESTING_TIMEOUT_SCALE
466 child.timeout = 5 * IPYTHON_TESTING_TIMEOUT_SCALE
469
467
470 child.expect("IPython")
468 child.expect("IPython")
471 child.expect("\n")
469 child.expect("\n")
472
470
473 ### we need a filename, so we need to exec the full block with a filename
471 ### we need a filename, so we need to exec the full block with a filename
474 with NamedTemporaryFile(suffix=".py", dir=".", delete=True) as tf:
472 with NamedTemporaryFile(suffix=".py", dir=".", delete=True) as tf:
475
473
476 name = tf.name[:-3].split("/")[-1]
474 name = tf.name[:-3].split("/")[-1]
477 tf.write("\n".join([dedent(x) for x in skip_decorators_blocks[:-1]]).encode())
475 tf.write("\n".join([dedent(x) for x in skip_decorators_blocks[:-1]]).encode())
478 tf.flush()
476 tf.flush()
479 codeblock = f"from {name} import f"
477 codeblock = f"from {name} import f"
480
478
481 dedented_blocks = [
479 dedented_blocks = [
482 codeblock,
480 codeblock,
483 "f()",
481 "f()",
484 ]
482 ]
485
483
486 in_prompt_number = 1
484 in_prompt_number = 1
487 for cblock in dedented_blocks:
485 for cblock in dedented_blocks:
488 child.expect_exact(f"In [{in_prompt_number}]:")
486 child.expect_exact(f"In [{in_prompt_number}]:")
489 in_prompt_number += 1
487 in_prompt_number += 1
490 for line in cblock.splitlines():
488 for line in cblock.splitlines():
491 child.sendline(line)
489 child.sendline(line)
492 child.expect_exact(line)
490 child.expect_exact(line)
493 child.sendline("")
491 child.sendline("")
494
492
495 # as the filename does not exists, we'll rely on the filename prompt
493 # as the filename does not exists, we'll rely on the filename prompt
496 child.expect_exact("47 bar(3, 4)")
494 child.expect_exact("47 bar(3, 4)")
497
495
498 for input_, expected in [
496 for input_, expected in [
499 (f"b {name}.py:3", ""),
497 (f"b {name}.py:3", ""),
500 ("step", "1---> 3 pass # should not stop here except"),
498 ("step", "1---> 3 pass # should not stop here except"),
501 ("step", "---> 38 @pdb_skipped_decorator"),
499 ("step", "---> 38 @pdb_skipped_decorator"),
502 ("continue", ""),
500 ("continue", ""),
503 ]:
501 ]:
504 child.expect("ipdb>")
502 child.expect("ipdb>")
505 child.sendline(input_)
503 child.sendline(input_)
506 child.expect_exact(input_)
504 child.expect_exact(input_)
507 child.expect_exact(expected)
505 child.expect_exact(expected)
508
506
509 child.close()
507 child.close()
510
508
511
509
512 @skip_win32
510 @skip_win32
513 def test_where_erase_value():
511 def test_where_erase_value():
514 """Test that `where` does not access f_locals and erase values."""
512 """Test that `where` does not access f_locals and erase values."""
515 import pexpect
513 import pexpect
516
514
517 env = os.environ.copy()
515 env = os.environ.copy()
518 env["IPY_TEST_SIMPLE_PROMPT"] = "1"
516 env["IPY_TEST_SIMPLE_PROMPT"] = "1"
519
517
520 child = pexpect.spawn(
518 child = pexpect.spawn(
521 sys.executable, ["-m", "IPython", "--colors=nocolor"], env=env
519 sys.executable, ["-m", "IPython", "--colors=nocolor"], env=env
522 )
520 )
523 child.timeout = 15 * IPYTHON_TESTING_TIMEOUT_SCALE
521 child.timeout = 15 * IPYTHON_TESTING_TIMEOUT_SCALE
524
522
525 child.expect("IPython")
523 child.expect("IPython")
526 child.expect("\n")
524 child.expect("\n")
527 child.expect_exact("In [1]")
525 child.expect_exact("In [1]")
528
526
529 block = dedent(
527 block = dedent(
530 """
528 """
531 def simple_f():
529 def simple_f():
532 myvar = 1
530 myvar = 1
533 print(myvar)
531 print(myvar)
534 1/0
532 1/0
535 print(myvar)
533 print(myvar)
536 simple_f() """
534 simple_f() """
537 )
535 )
538
536
539 for line in block.splitlines():
537 for line in block.splitlines():
540 child.sendline(line)
538 child.sendline(line)
541 child.expect_exact(line)
539 child.expect_exact(line)
542 child.expect_exact("ZeroDivisionError")
540 child.expect_exact("ZeroDivisionError")
543 child.expect_exact("In [2]:")
541 child.expect_exact("In [2]:")
544
542
545 child.sendline("%debug")
543 child.sendline("%debug")
546
544
547 ##
545 ##
548 child.expect("ipdb>")
546 child.expect("ipdb>")
549
547
550 child.sendline("myvar")
548 child.sendline("myvar")
551 child.expect("1")
549 child.expect("1")
552
550
553 ##
551 ##
554 child.expect("ipdb>")
552 child.expect("ipdb>")
555
553
556 child.sendline("myvar = 2")
554 child.sendline("myvar = 2")
557
555
558 ##
556 ##
559 child.expect_exact("ipdb>")
557 child.expect_exact("ipdb>")
560
558
561 child.sendline("myvar")
559 child.sendline("myvar")
562
560
563 child.expect_exact("2")
561 child.expect_exact("2")
564
562
565 ##
563 ##
566 child.expect("ipdb>")
564 child.expect("ipdb>")
567 child.sendline("where")
565 child.sendline("where")
568
566
569 ##
567 ##
570 child.expect("ipdb>")
568 child.expect("ipdb>")
571 child.sendline("myvar")
569 child.sendline("myvar")
572
570
573 child.expect_exact("2")
571 child.expect_exact("2")
574 child.expect("ipdb>")
572 child.expect("ipdb>")
575
573
576 child.close()
574 child.close()
General Comments 0
You need to be logged in to leave comments. Login now