blob: b98fe19816f7278c85cfd649ef47040aae3c0f71 [file] [log] [blame]
Georg Brandl4d4313d2009-05-05 08:54:11 +00001# A test suite for pdb; at the moment, this only validates skipping of
2# specified test modules (RFE #5142).
3
4import imp
Georg Brandl4d4313d2009-05-05 08:54:11 +00005import sys
Jason R. Coombs5d032c02011-11-17 18:03:24 -05006import os
7import unittest
8import subprocess
Senthil Kumaran7f6d4e12012-05-01 10:36:28 +08009import textwrap
Georg Brandl4d4313d2009-05-05 08:54:11 +000010
11from test import test_support
12# This little helper class is essential for testing pdb under doctest.
13from test_doctest import _FakeInput
14
15
Senthil Kumaran7f6d4e12012-05-01 10:36:28 +080016class PdbTestCase(unittest.TestCase):
17
18 def run_pdb(self, script, commands):
19 """Run 'script' lines with pdb and the pdb 'commands'."""
20 filename = 'main.py'
21 with open(filename, 'w') as f:
22 f.write(textwrap.dedent(script))
Georg Brandl9f9970b2012-05-06 11:53:51 +020023 self.addCleanup(test_support.unlink, filename)
Senthil Kumaran7f6d4e12012-05-01 10:36:28 +080024 cmd = [sys.executable, '-m', 'pdb', filename]
25 stdout = stderr = None
26 proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
27 stdin=subprocess.PIPE,
28 stderr=subprocess.STDOUT,
29 )
30 stdout, stderr = proc.communicate(commands)
31 proc.stdout.close()
32 proc.stdin.close()
33 return stdout, stderr
34
35 def test_issue13183(self):
36 script = """
37 from bar import bar
38
39 def foo():
40 bar()
41
42 def nope():
43 pass
44
45 def foobar():
46 foo()
47 nope()
48
49 foobar()
50 """
51 commands = """
52 from bar import bar
53 break bar
54 continue
55 step
56 step
57 quit
58 """
59 bar = """
60 def bar():
Senthil Kumarana9e18cd2012-05-02 07:59:36 +080061 pass
Senthil Kumaran7f6d4e12012-05-01 10:36:28 +080062 """
63 with open('bar.py', 'w') as f:
64 f.write(textwrap.dedent(bar))
Georg Brandl9f9970b2012-05-06 11:53:51 +020065 self.addCleanup(test_support.unlink, 'bar.py')
Victor Stinnerffaa0312015-03-30 01:24:57 +020066 self.addCleanup(test_support.unlink, 'bar.pyc')
Senthil Kumaran7f6d4e12012-05-01 10:36:28 +080067 stdout, stderr = self.run_pdb(script, commands)
Georg Brandl9f9970b2012-05-06 11:53:51 +020068 self.assertTrue(
69 any('main.py(5)foo()->None' in l for l in stdout.splitlines()),
70 'Fail to step into the caller after a return')
Senthil Kumaran7f6d4e12012-05-01 10:36:28 +080071
Terry Jan Reedy23ae4882015-09-05 19:13:17 -040072 def test_issue16180(self):
73 # A syntax error in the debuggee.
74 script = "def f: pass\n"
75 commands = ''
76 expected = "SyntaxError:"
77 stdout, stderr = self.run_pdb(script, commands)
78 self.assertIn(expected, stdout,
79 '\n\nExpected:\n{}\nGot:\n{}\n'
80 'Fail to handle a syntax error in the debuggee.'
81 .format(expected, stdout))
82
Senthil Kumaran7f6d4e12012-05-01 10:36:28 +080083
Georg Brandl6c39f062009-09-16 16:22:12 +000084class PdbTestInput(object):
85 """Context manager that makes testing Pdb in doctests easier."""
86
87 def __init__(self, input):
88 self.input = input
89
90 def __enter__(self):
91 self.real_stdin = sys.stdin
92 sys.stdin = _FakeInput(self.input)
93
94 def __exit__(self, *exc):
95 sys.stdin = self.real_stdin
96
97
Georg Brandl69dfe8d2009-09-16 16:36:39 +000098def write(x):
99 print x
100
101def test_pdb_displayhook():
102 """This tests the custom displayhook for pdb.
103
104 >>> def test_function(foo, bar):
105 ... import pdb; pdb.Pdb().set_trace()
106 ... pass
107
108 >>> with PdbTestInput([
109 ... 'foo',
110 ... 'bar',
111 ... 'for i in range(5): write(i)',
112 ... 'continue',
113 ... ]):
114 ... test_function(1, None)
115 > <doctest test.test_pdb.test_pdb_displayhook[0]>(3)test_function()
116 -> pass
117 (Pdb) foo
118 1
119 (Pdb) bar
120 (Pdb) for i in range(5): write(i)
121 0
122 1
123 2
124 3
125 4
126 (Pdb) continue
127 """
128
Senthil Kumaran9a5897b2010-11-29 12:41:03 +0000129def test_pdb_breakpoint_commands():
130 """Test basic commands related to breakpoints.
131
132 >>> def test_function():
133 ... import pdb; pdb.Pdb().set_trace()
134 ... print(1)
135 ... print(2)
136 ... print(3)
137 ... print(4)
138
139 First, need to clear bdb state that might be left over from previous tests.
140 Otherwise, the new breakpoints might get assigned different numbers.
141
142 >>> from bdb import Breakpoint
143 >>> Breakpoint.next = 1
144 >>> Breakpoint.bplist = {}
145 >>> Breakpoint.bpbynumber = [None]
146
147 Now test the breakpoint commands. NORMALIZE_WHITESPACE is needed because
148 the breakpoint list outputs a tab for the "stop only" and "ignore next"
149 lines, which we don't want to put in here.
150
151 >>> with PdbTestInput([ # doctest: +NORMALIZE_WHITESPACE
152 ... 'break 3',
153 ... 'disable 1',
154 ... 'ignore 1 10',
155 ... 'condition 1 1 < 2',
156 ... 'break 4',
157 ... 'break 4',
158 ... 'break',
159 ... 'clear 3',
160 ... 'break',
161 ... 'condition 1',
162 ... 'enable 1',
163 ... 'clear 1',
164 ... 'commands 2',
165 ... 'print 42',
166 ... 'end',
167 ... 'continue', # will stop at breakpoint 2 (line 4)
168 ... 'clear', # clear all!
169 ... 'y',
170 ... 'tbreak 5',
171 ... 'continue', # will stop at temporary breakpoint
172 ... 'break', # make sure breakpoint is gone
173 ... 'continue',
174 ... ]):
175 ... test_function()
176 > <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>(3)test_function()
177 -> print(1)
178 (Pdb) break 3
179 Breakpoint 1 at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:3
180 (Pdb) disable 1
181 (Pdb) ignore 1 10
182 Will ignore next 10 crossings of breakpoint 1.
183 (Pdb) condition 1 1 < 2
184 (Pdb) break 4
185 Breakpoint 2 at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:4
186 (Pdb) break 4
187 Breakpoint 3 at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:4
188 (Pdb) break
189 Num Type Disp Enb Where
190 1 breakpoint keep no at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:3
191 stop only if 1 < 2
192 ignore next 10 hits
193 2 breakpoint keep yes at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:4
194 3 breakpoint keep yes at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:4
195 (Pdb) clear 3
196 Deleted breakpoint 3
197 (Pdb) break
198 Num Type Disp Enb Where
199 1 breakpoint keep no at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:3
200 stop only if 1 < 2
201 ignore next 10 hits
202 2 breakpoint keep yes at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:4
203 (Pdb) condition 1
204 Breakpoint 1 is now unconditional.
205 (Pdb) enable 1
206 (Pdb) clear 1
207 Deleted breakpoint 1
208 (Pdb) commands 2
209 (com) print 42
210 (com) end
211 (Pdb) continue
212 1
213 42
214 > <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>(4)test_function()
215 -> print(2)
216 (Pdb) clear
217 Clear all breaks? y
218 (Pdb) tbreak 5
219 Breakpoint 4 at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:5
220 (Pdb) continue
221 2
222 Deleted breakpoint 4
223 > <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>(5)test_function()
224 -> print(3)
225 (Pdb) break
226 (Pdb) continue
227 3
228 4
229 """
230
Georg Brandl69dfe8d2009-09-16 16:36:39 +0000231
Georg Brandl4d4313d2009-05-05 08:54:11 +0000232def test_pdb_skip_modules():
233 """This illustrates the simple case of module skipping.
234
235 >>> def skip_module():
236 ... import string
Georg Brandl6c39f062009-09-16 16:22:12 +0000237 ... import pdb; pdb.Pdb(skip=['string*']).set_trace()
Georg Brandl4d4313d2009-05-05 08:54:11 +0000238 ... string.lower('FOO')
Georg Brandl4d4313d2009-05-05 08:54:11 +0000239
Georg Brandl6c39f062009-09-16 16:22:12 +0000240 >>> with PdbTestInput([
241 ... 'step',
Georg Brandl69dfe8d2009-09-16 16:36:39 +0000242 ... 'continue',
Georg Brandl6c39f062009-09-16 16:22:12 +0000243 ... ]):
Georg Brandl4d4313d2009-05-05 08:54:11 +0000244 ... skip_module()
Georg Brandl4d4313d2009-05-05 08:54:11 +0000245 > <doctest test.test_pdb.test_pdb_skip_modules[0]>(4)skip_module()
246 -> string.lower('FOO')
247 (Pdb) step
248 --Return--
249 > <doctest test.test_pdb.test_pdb_skip_modules[0]>(4)skip_module()->None
250 -> string.lower('FOO')
251 (Pdb) continue
Georg Brandl6c39f062009-09-16 16:22:12 +0000252 """
Georg Brandl4d4313d2009-05-05 08:54:11 +0000253
254
255# Module for testing skipping of module that makes a callback
256mod = imp.new_module('module_to_skip')
257exec 'def foo_pony(callback): x = 1; callback(); return None' in mod.__dict__
258
259
260def test_pdb_skip_modules_with_callback():
261 """This illustrates skipping of modules that call into other code.
262
263 >>> def skip_module():
264 ... def callback():
265 ... return None
Georg Brandl6c39f062009-09-16 16:22:12 +0000266 ... import pdb; pdb.Pdb(skip=['module_to_skip*']).set_trace()
Georg Brandl4d4313d2009-05-05 08:54:11 +0000267 ... mod.foo_pony(callback)
Georg Brandl4d4313d2009-05-05 08:54:11 +0000268
Georg Brandl6c39f062009-09-16 16:22:12 +0000269 >>> with PdbTestInput([
270 ... 'step',
271 ... 'step',
272 ... 'step',
273 ... 'step',
274 ... 'step',
275 ... 'continue',
276 ... ]):
Georg Brandl4d4313d2009-05-05 08:54:11 +0000277 ... skip_module()
Georg Brandl6c39f062009-09-16 16:22:12 +0000278 ... pass # provides something to "step" to
Georg Brandl4d4313d2009-05-05 08:54:11 +0000279 > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[0]>(5)skip_module()
280 -> mod.foo_pony(callback)
281 (Pdb) step
282 --Call--
283 > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[0]>(2)callback()
284 -> def callback():
285 (Pdb) step
286 > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[0]>(3)callback()
287 -> return None
288 (Pdb) step
289 --Return--
290 > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[0]>(3)callback()->None
291 -> return None
292 (Pdb) step
293 --Return--
294 > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[0]>(5)skip_module()->None
295 -> mod.foo_pony(callback)
296 (Pdb) step
Georg Brandl6c39f062009-09-16 16:22:12 +0000297 > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[1]>(10)<module>()
298 -> pass # provides something to "step" to
Georg Brandl4d4313d2009-05-05 08:54:11 +0000299 (Pdb) continue
Georg Brandl6c39f062009-09-16 16:22:12 +0000300 """
Georg Brandl4d4313d2009-05-05 08:54:11 +0000301
302
Georg Brandl50775992010-08-01 19:33:15 +0000303def test_pdb_continue_in_bottomframe():
304 """Test that "continue" and "next" work properly in bottom frame (issue #5294).
305
306 >>> def test_function():
307 ... import pdb, sys; inst = pdb.Pdb()
308 ... inst.set_trace()
309 ... inst.botframe = sys._getframe() # hackery to get the right botframe
310 ... print(1)
311 ... print(2)
312 ... print(3)
313 ... print(4)
314
Senthil Kumaran9a5897b2010-11-29 12:41:03 +0000315 First, need to clear bdb state that might be left over from previous tests.
316 Otherwise, the new breakpoints might get assigned different numbers.
317
318 >>> from bdb import Breakpoint
319 >>> Breakpoint.next = 1
320 >>> Breakpoint.bplist = {}
321 >>> Breakpoint.bpbynumber = [None]
322
Georg Brandl50775992010-08-01 19:33:15 +0000323 >>> with PdbTestInput([
324 ... 'next',
325 ... 'break 7',
326 ... 'continue',
327 ... 'next',
328 ... 'continue',
329 ... 'continue',
330 ... ]):
331 ... test_function()
332 > <doctest test.test_pdb.test_pdb_continue_in_bottomframe[0]>(4)test_function()
333 -> inst.botframe = sys._getframe() # hackery to get the right botframe
334 (Pdb) next
335 > <doctest test.test_pdb.test_pdb_continue_in_bottomframe[0]>(5)test_function()
336 -> print(1)
337 (Pdb) break 7
338 Breakpoint 1 at <doctest test.test_pdb.test_pdb_continue_in_bottomframe[0]>:7
339 (Pdb) continue
340 1
341 2
342 > <doctest test.test_pdb.test_pdb_continue_in_bottomframe[0]>(7)test_function()
343 -> print(3)
344 (Pdb) next
345 3
346 > <doctest test.test_pdb.test_pdb_continue_in_bottomframe[0]>(8)test_function()
347 -> print(4)
348 (Pdb) continue
349 4
350 """
351
Jason R. Coombs77cd2582011-12-08 22:14:56 -0500352class ModuleInitTester(unittest.TestCase):
Jason R. Coombs5d032c02011-11-17 18:03:24 -0500353
Jason R. Coombs77cd2582011-12-08 22:14:56 -0500354 def test_filename_correct(self):
355 """
356 In issue 7750, it was found that if the filename has a sequence that
357 resolves to an escape character in a Python string (such as \t), it
358 will be treated as the escaped character.
359 """
360 # the test_fn must contain something like \t
361 # on Windows, this will create 'test_mod.py' in the current directory.
362 # on Unix, this will create '.\test_mod.py' in the current directory.
363 test_fn = '.\\test_mod.py'
364 code = 'print("testing pdb")'
365 with open(test_fn, 'w') as f:
366 f.write(code)
367 self.addCleanup(os.remove, test_fn)
368 cmd = [sys.executable, '-m', 'pdb', test_fn,]
Jason R. Coombs5d032c02011-11-17 18:03:24 -0500369 proc = subprocess.Popen(cmd,
370 stdout=subprocess.PIPE,
371 stdin=subprocess.PIPE,
372 stderr=subprocess.STDOUT,
373 )
374 stdout, stderr = proc.communicate('quit\n')
Jason R. Coombs77cd2582011-12-08 22:14:56 -0500375 self.assertIn(code, stdout, "pdb munged the filename")
Jason R. Coombs5d032c02011-11-17 18:03:24 -0500376
Georg Brandl50775992010-08-01 19:33:15 +0000377
Georg Brandl4d4313d2009-05-05 08:54:11 +0000378def test_main():
379 from test import test_pdb
380 test_support.run_doctest(test_pdb, verbosity=True)
Senthil Kumaran7f6d4e12012-05-01 10:36:28 +0800381 test_support.run_unittest(
382 PdbTestCase,
383 ModuleInitTester)
Georg Brandl4d4313d2009-05-05 08:54:11 +0000384
385if __name__ == '__main__':
386 test_main()