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