blob: b6dd2b7370dc8f53664fff68fc22cc753929404f [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
72
Georg Brandl6c39f062009-09-16 16:22:12 +000073class PdbTestInput(object):
74 """Context manager that makes testing Pdb in doctests easier."""
75
76 def __init__(self, input):
77 self.input = input
78
79 def __enter__(self):
80 self.real_stdin = sys.stdin
81 sys.stdin = _FakeInput(self.input)
82
83 def __exit__(self, *exc):
84 sys.stdin = self.real_stdin
85
86
Georg Brandl69dfe8d2009-09-16 16:36:39 +000087def write(x):
88 print x
89
90def test_pdb_displayhook():
91 """This tests the custom displayhook for pdb.
92
93 >>> def test_function(foo, bar):
94 ... import pdb; pdb.Pdb().set_trace()
95 ... pass
96
97 >>> with PdbTestInput([
98 ... 'foo',
99 ... 'bar',
100 ... 'for i in range(5): write(i)',
101 ... 'continue',
102 ... ]):
103 ... test_function(1, None)
104 > <doctest test.test_pdb.test_pdb_displayhook[0]>(3)test_function()
105 -> pass
106 (Pdb) foo
107 1
108 (Pdb) bar
109 (Pdb) for i in range(5): write(i)
110 0
111 1
112 2
113 3
114 4
115 (Pdb) continue
116 """
117
Senthil Kumaran9a5897b2010-11-29 12:41:03 +0000118def test_pdb_breakpoint_commands():
119 """Test basic commands related to breakpoints.
120
121 >>> def test_function():
122 ... import pdb; pdb.Pdb().set_trace()
123 ... print(1)
124 ... print(2)
125 ... print(3)
126 ... print(4)
127
128 First, need to clear bdb state that might be left over from previous tests.
129 Otherwise, the new breakpoints might get assigned different numbers.
130
131 >>> from bdb import Breakpoint
132 >>> Breakpoint.next = 1
133 >>> Breakpoint.bplist = {}
134 >>> Breakpoint.bpbynumber = [None]
135
136 Now test the breakpoint commands. NORMALIZE_WHITESPACE is needed because
137 the breakpoint list outputs a tab for the "stop only" and "ignore next"
138 lines, which we don't want to put in here.
139
140 >>> with PdbTestInput([ # doctest: +NORMALIZE_WHITESPACE
141 ... 'break 3',
142 ... 'disable 1',
143 ... 'ignore 1 10',
144 ... 'condition 1 1 < 2',
145 ... 'break 4',
146 ... 'break 4',
147 ... 'break',
148 ... 'clear 3',
149 ... 'break',
150 ... 'condition 1',
151 ... 'enable 1',
152 ... 'clear 1',
153 ... 'commands 2',
154 ... 'print 42',
155 ... 'end',
156 ... 'continue', # will stop at breakpoint 2 (line 4)
157 ... 'clear', # clear all!
158 ... 'y',
159 ... 'tbreak 5',
160 ... 'continue', # will stop at temporary breakpoint
161 ... 'break', # make sure breakpoint is gone
162 ... 'continue',
163 ... ]):
164 ... test_function()
165 > <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>(3)test_function()
166 -> print(1)
167 (Pdb) break 3
168 Breakpoint 1 at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:3
169 (Pdb) disable 1
170 (Pdb) ignore 1 10
171 Will ignore next 10 crossings of breakpoint 1.
172 (Pdb) condition 1 1 < 2
173 (Pdb) break 4
174 Breakpoint 2 at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:4
175 (Pdb) break 4
176 Breakpoint 3 at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:4
177 (Pdb) break
178 Num Type Disp Enb Where
179 1 breakpoint keep no at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:3
180 stop only if 1 < 2
181 ignore next 10 hits
182 2 breakpoint keep yes at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:4
183 3 breakpoint keep yes at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:4
184 (Pdb) clear 3
185 Deleted breakpoint 3
186 (Pdb) break
187 Num Type Disp Enb Where
188 1 breakpoint keep no at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:3
189 stop only if 1 < 2
190 ignore next 10 hits
191 2 breakpoint keep yes at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:4
192 (Pdb) condition 1
193 Breakpoint 1 is now unconditional.
194 (Pdb) enable 1
195 (Pdb) clear 1
196 Deleted breakpoint 1
197 (Pdb) commands 2
198 (com) print 42
199 (com) end
200 (Pdb) continue
201 1
202 42
203 > <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>(4)test_function()
204 -> print(2)
205 (Pdb) clear
206 Clear all breaks? y
207 (Pdb) tbreak 5
208 Breakpoint 4 at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:5
209 (Pdb) continue
210 2
211 Deleted breakpoint 4
212 > <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>(5)test_function()
213 -> print(3)
214 (Pdb) break
215 (Pdb) continue
216 3
217 4
218 """
219
Georg Brandl69dfe8d2009-09-16 16:36:39 +0000220
Georg Brandl4d4313d2009-05-05 08:54:11 +0000221def test_pdb_skip_modules():
222 """This illustrates the simple case of module skipping.
223
224 >>> def skip_module():
225 ... import string
Georg Brandl6c39f062009-09-16 16:22:12 +0000226 ... import pdb; pdb.Pdb(skip=['string*']).set_trace()
Georg Brandl4d4313d2009-05-05 08:54:11 +0000227 ... string.lower('FOO')
Georg Brandl4d4313d2009-05-05 08:54:11 +0000228
Georg Brandl6c39f062009-09-16 16:22:12 +0000229 >>> with PdbTestInput([
230 ... 'step',
Georg Brandl69dfe8d2009-09-16 16:36:39 +0000231 ... 'continue',
Georg Brandl6c39f062009-09-16 16:22:12 +0000232 ... ]):
Georg Brandl4d4313d2009-05-05 08:54:11 +0000233 ... skip_module()
Georg Brandl4d4313d2009-05-05 08:54:11 +0000234 > <doctest test.test_pdb.test_pdb_skip_modules[0]>(4)skip_module()
235 -> string.lower('FOO')
236 (Pdb) step
237 --Return--
238 > <doctest test.test_pdb.test_pdb_skip_modules[0]>(4)skip_module()->None
239 -> string.lower('FOO')
240 (Pdb) continue
Georg Brandl6c39f062009-09-16 16:22:12 +0000241 """
Georg Brandl4d4313d2009-05-05 08:54:11 +0000242
243
244# Module for testing skipping of module that makes a callback
245mod = imp.new_module('module_to_skip')
246exec 'def foo_pony(callback): x = 1; callback(); return None' in mod.__dict__
247
248
249def test_pdb_skip_modules_with_callback():
250 """This illustrates skipping of modules that call into other code.
251
252 >>> def skip_module():
253 ... def callback():
254 ... return None
Georg Brandl6c39f062009-09-16 16:22:12 +0000255 ... import pdb; pdb.Pdb(skip=['module_to_skip*']).set_trace()
Georg Brandl4d4313d2009-05-05 08:54:11 +0000256 ... mod.foo_pony(callback)
Georg Brandl4d4313d2009-05-05 08:54:11 +0000257
Georg Brandl6c39f062009-09-16 16:22:12 +0000258 >>> with PdbTestInput([
259 ... 'step',
260 ... 'step',
261 ... 'step',
262 ... 'step',
263 ... 'step',
264 ... 'continue',
265 ... ]):
Georg Brandl4d4313d2009-05-05 08:54:11 +0000266 ... skip_module()
Georg Brandl6c39f062009-09-16 16:22:12 +0000267 ... pass # provides something to "step" to
Georg Brandl4d4313d2009-05-05 08:54:11 +0000268 > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[0]>(5)skip_module()
269 -> mod.foo_pony(callback)
270 (Pdb) step
271 --Call--
272 > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[0]>(2)callback()
273 -> def callback():
274 (Pdb) step
275 > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[0]>(3)callback()
276 -> return None
277 (Pdb) step
278 --Return--
279 > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[0]>(3)callback()->None
280 -> return None
281 (Pdb) step
282 --Return--
283 > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[0]>(5)skip_module()->None
284 -> mod.foo_pony(callback)
285 (Pdb) step
Georg Brandl6c39f062009-09-16 16:22:12 +0000286 > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[1]>(10)<module>()
287 -> pass # provides something to "step" to
Georg Brandl4d4313d2009-05-05 08:54:11 +0000288 (Pdb) continue
Georg Brandl6c39f062009-09-16 16:22:12 +0000289 """
Georg Brandl4d4313d2009-05-05 08:54:11 +0000290
291
Georg Brandl50775992010-08-01 19:33:15 +0000292def test_pdb_continue_in_bottomframe():
293 """Test that "continue" and "next" work properly in bottom frame (issue #5294).
294
295 >>> def test_function():
296 ... import pdb, sys; inst = pdb.Pdb()
297 ... inst.set_trace()
298 ... inst.botframe = sys._getframe() # hackery to get the right botframe
299 ... print(1)
300 ... print(2)
301 ... print(3)
302 ... print(4)
303
Senthil Kumaran9a5897b2010-11-29 12:41:03 +0000304 First, need to clear bdb state that might be left over from previous tests.
305 Otherwise, the new breakpoints might get assigned different numbers.
306
307 >>> from bdb import Breakpoint
308 >>> Breakpoint.next = 1
309 >>> Breakpoint.bplist = {}
310 >>> Breakpoint.bpbynumber = [None]
311
Georg Brandl50775992010-08-01 19:33:15 +0000312 >>> with PdbTestInput([
313 ... 'next',
314 ... 'break 7',
315 ... 'continue',
316 ... 'next',
317 ... 'continue',
318 ... 'continue',
319 ... ]):
320 ... test_function()
321 > <doctest test.test_pdb.test_pdb_continue_in_bottomframe[0]>(4)test_function()
322 -> inst.botframe = sys._getframe() # hackery to get the right botframe
323 (Pdb) next
324 > <doctest test.test_pdb.test_pdb_continue_in_bottomframe[0]>(5)test_function()
325 -> print(1)
326 (Pdb) break 7
327 Breakpoint 1 at <doctest test.test_pdb.test_pdb_continue_in_bottomframe[0]>:7
328 (Pdb) continue
329 1
330 2
331 > <doctest test.test_pdb.test_pdb_continue_in_bottomframe[0]>(7)test_function()
332 -> print(3)
333 (Pdb) next
334 3
335 > <doctest test.test_pdb.test_pdb_continue_in_bottomframe[0]>(8)test_function()
336 -> print(4)
337 (Pdb) continue
338 4
339 """
340
Jason R. Coombs77cd2582011-12-08 22:14:56 -0500341class ModuleInitTester(unittest.TestCase):
Jason R. Coombs5d032c02011-11-17 18:03:24 -0500342
Jason R. Coombs77cd2582011-12-08 22:14:56 -0500343 def test_filename_correct(self):
344 """
345 In issue 7750, it was found that if the filename has a sequence that
346 resolves to an escape character in a Python string (such as \t), it
347 will be treated as the escaped character.
348 """
349 # the test_fn must contain something like \t
350 # on Windows, this will create 'test_mod.py' in the current directory.
351 # on Unix, this will create '.\test_mod.py' in the current directory.
352 test_fn = '.\\test_mod.py'
353 code = 'print("testing pdb")'
354 with open(test_fn, 'w') as f:
355 f.write(code)
356 self.addCleanup(os.remove, test_fn)
357 cmd = [sys.executable, '-m', 'pdb', test_fn,]
Jason R. Coombs5d032c02011-11-17 18:03:24 -0500358 proc = subprocess.Popen(cmd,
359 stdout=subprocess.PIPE,
360 stdin=subprocess.PIPE,
361 stderr=subprocess.STDOUT,
362 )
363 stdout, stderr = proc.communicate('quit\n')
Jason R. Coombs77cd2582011-12-08 22:14:56 -0500364 self.assertIn(code, stdout, "pdb munged the filename")
Jason R. Coombs5d032c02011-11-17 18:03:24 -0500365
Georg Brandl50775992010-08-01 19:33:15 +0000366
Georg Brandl4d4313d2009-05-05 08:54:11 +0000367def test_main():
368 from test import test_pdb
369 test_support.run_doctest(test_pdb, verbosity=True)
Senthil Kumaran7f6d4e12012-05-01 10:36:28 +0800370 test_support.run_unittest(
371 PdbTestCase,
372 ModuleInitTester)
Georg Brandl4d4313d2009-05-05 08:54:11 +0000373
374if __name__ == '__main__':
375 test_main()