test_pdb.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. # A test suite for pdb; at the moment, this only validates skipping of
  2. # specified test modules (RFE #5142).
  3. import imp
  4. import sys
  5. import os
  6. import unittest
  7. import subprocess
  8. import textwrap
  9. from test import test_support
  10. # This little helper class is essential for testing pdb under doctest.
  11. from test_doctest import _FakeInput
  12. class PdbTestCase(unittest.TestCase):
  13. def run_pdb(self, script, commands):
  14. """Run 'script' lines with pdb and the pdb 'commands'."""
  15. filename = 'main.py'
  16. with open(filename, 'w') as f:
  17. f.write(textwrap.dedent(script))
  18. self.addCleanup(test_support.unlink, filename)
  19. cmd = [sys.executable, '-m', 'pdb', filename]
  20. stdout = stderr = None
  21. proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
  22. stdin=subprocess.PIPE,
  23. stderr=subprocess.STDOUT,
  24. )
  25. stdout, stderr = proc.communicate(commands)
  26. proc.stdout.close()
  27. proc.stdin.close()
  28. return stdout, stderr
  29. def test_issue13183(self):
  30. script = """
  31. from bar import bar
  32. def foo():
  33. bar()
  34. def nope():
  35. pass
  36. def foobar():
  37. foo()
  38. nope()
  39. foobar()
  40. """
  41. commands = """
  42. from bar import bar
  43. break bar
  44. continue
  45. step
  46. step
  47. quit
  48. """
  49. bar = """
  50. def bar():
  51. pass
  52. """
  53. with open('bar.py', 'w') as f:
  54. f.write(textwrap.dedent(bar))
  55. self.addCleanup(test_support.unlink, 'bar.py')
  56. self.addCleanup(test_support.unlink, 'bar.pyc')
  57. stdout, stderr = self.run_pdb(script, commands)
  58. self.assertTrue(
  59. any('main.py(5)foo()->None' in l for l in stdout.splitlines()),
  60. 'Fail to step into the caller after a return')
  61. def test_issue16180(self):
  62. # A syntax error in the debuggee.
  63. script = "def f: pass\n"
  64. commands = ''
  65. expected = "SyntaxError:"
  66. stdout, stderr = self.run_pdb(script, commands)
  67. self.assertIn(expected, stdout,
  68. '\n\nExpected:\n{}\nGot:\n{}\n'
  69. 'Fail to handle a syntax error in the debuggee.'
  70. .format(expected, stdout))
  71. class PdbTestInput(object):
  72. """Context manager that makes testing Pdb in doctests easier."""
  73. def __init__(self, input):
  74. self.input = input
  75. def __enter__(self):
  76. self.real_stdin = sys.stdin
  77. sys.stdin = _FakeInput(self.input)
  78. def __exit__(self, *exc):
  79. sys.stdin = self.real_stdin
  80. def write(x):
  81. print x
  82. def test_pdb_displayhook():
  83. """This tests the custom displayhook for pdb.
  84. >>> def test_function(foo, bar):
  85. ... import pdb; pdb.Pdb().set_trace()
  86. ... pass
  87. >>> with PdbTestInput([
  88. ... 'foo',
  89. ... 'bar',
  90. ... 'for i in range(5): write(i)',
  91. ... 'continue',
  92. ... ]):
  93. ... test_function(1, None)
  94. > <doctest test.test_pdb.test_pdb_displayhook[0]>(3)test_function()
  95. -> pass
  96. (Pdb) foo
  97. 1
  98. (Pdb) bar
  99. (Pdb) for i in range(5): write(i)
  100. 0
  101. 1
  102. 2
  103. 3
  104. 4
  105. (Pdb) continue
  106. """
  107. def test_pdb_breakpoint_commands():
  108. """Test basic commands related to breakpoints.
  109. >>> def test_function():
  110. ... import pdb; pdb.Pdb().set_trace()
  111. ... print(1)
  112. ... print(2)
  113. ... print(3)
  114. ... print(4)
  115. First, need to clear bdb state that might be left over from previous tests.
  116. Otherwise, the new breakpoints might get assigned different numbers.
  117. >>> from bdb import Breakpoint
  118. >>> Breakpoint.next = 1
  119. >>> Breakpoint.bplist = {}
  120. >>> Breakpoint.bpbynumber = [None]
  121. Now test the breakpoint commands. NORMALIZE_WHITESPACE is needed because
  122. the breakpoint list outputs a tab for the "stop only" and "ignore next"
  123. lines, which we don't want to put in here.
  124. >>> with PdbTestInput([ # doctest: +NORMALIZE_WHITESPACE
  125. ... 'break 3',
  126. ... 'disable 1',
  127. ... 'ignore 1 10',
  128. ... 'condition 1 1 < 2',
  129. ... 'break 4',
  130. ... 'break 4',
  131. ... 'break',
  132. ... 'clear 3',
  133. ... 'break',
  134. ... 'condition 1',
  135. ... 'enable 1',
  136. ... 'clear 1',
  137. ... 'commands 2',
  138. ... 'print 42',
  139. ... 'end',
  140. ... 'continue', # will stop at breakpoint 2 (line 4)
  141. ... 'clear', # clear all!
  142. ... 'y',
  143. ... 'tbreak 5',
  144. ... 'continue', # will stop at temporary breakpoint
  145. ... 'break', # make sure breakpoint is gone
  146. ... 'continue',
  147. ... ]):
  148. ... test_function()
  149. > <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>(3)test_function()
  150. -> print(1)
  151. (Pdb) break 3
  152. Breakpoint 1 at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:3
  153. (Pdb) disable 1
  154. (Pdb) ignore 1 10
  155. Will ignore next 10 crossings of breakpoint 1.
  156. (Pdb) condition 1 1 < 2
  157. (Pdb) break 4
  158. Breakpoint 2 at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:4
  159. (Pdb) break 4
  160. Breakpoint 3 at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:4
  161. (Pdb) break
  162. Num Type Disp Enb Where
  163. 1 breakpoint keep no at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:3
  164. stop only if 1 < 2
  165. ignore next 10 hits
  166. 2 breakpoint keep yes at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:4
  167. 3 breakpoint keep yes at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:4
  168. (Pdb) clear 3
  169. Deleted breakpoint 3
  170. (Pdb) break
  171. Num Type Disp Enb Where
  172. 1 breakpoint keep no at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:3
  173. stop only if 1 < 2
  174. ignore next 10 hits
  175. 2 breakpoint keep yes at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:4
  176. (Pdb) condition 1
  177. Breakpoint 1 is now unconditional.
  178. (Pdb) enable 1
  179. (Pdb) clear 1
  180. Deleted breakpoint 1
  181. (Pdb) commands 2
  182. (com) print 42
  183. (com) end
  184. (Pdb) continue
  185. 1
  186. 42
  187. > <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>(4)test_function()
  188. -> print(2)
  189. (Pdb) clear
  190. Clear all breaks? y
  191. (Pdb) tbreak 5
  192. Breakpoint 4 at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:5
  193. (Pdb) continue
  194. 2
  195. Deleted breakpoint 4
  196. > <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>(5)test_function()
  197. -> print(3)
  198. (Pdb) break
  199. (Pdb) continue
  200. 3
  201. 4
  202. """
  203. def test_pdb_skip_modules():
  204. """This illustrates the simple case of module skipping.
  205. >>> def skip_module():
  206. ... import string
  207. ... import pdb; pdb.Pdb(skip=['string*']).set_trace()
  208. ... string.lower('FOO')
  209. >>> with PdbTestInput([
  210. ... 'step',
  211. ... 'continue',
  212. ... ]):
  213. ... skip_module()
  214. > <doctest test.test_pdb.test_pdb_skip_modules[0]>(4)skip_module()
  215. -> string.lower('FOO')
  216. (Pdb) step
  217. --Return--
  218. > <doctest test.test_pdb.test_pdb_skip_modules[0]>(4)skip_module()->None
  219. -> string.lower('FOO')
  220. (Pdb) continue
  221. """
  222. # Module for testing skipping of module that makes a callback
  223. mod = imp.new_module('module_to_skip')
  224. exec 'def foo_pony(callback): x = 1; callback(); return None' in mod.__dict__
  225. def test_pdb_skip_modules_with_callback():
  226. """This illustrates skipping of modules that call into other code.
  227. >>> def skip_module():
  228. ... def callback():
  229. ... return None
  230. ... import pdb; pdb.Pdb(skip=['module_to_skip*']).set_trace()
  231. ... mod.foo_pony(callback)
  232. >>> with PdbTestInput([
  233. ... 'step',
  234. ... 'step',
  235. ... 'step',
  236. ... 'step',
  237. ... 'step',
  238. ... 'continue',
  239. ... ]):
  240. ... skip_module()
  241. ... pass # provides something to "step" to
  242. > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[0]>(5)skip_module()
  243. -> mod.foo_pony(callback)
  244. (Pdb) step
  245. --Call--
  246. > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[0]>(2)callback()
  247. -> def callback():
  248. (Pdb) step
  249. > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[0]>(3)callback()
  250. -> return None
  251. (Pdb) step
  252. --Return--
  253. > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[0]>(3)callback()->None
  254. -> return None
  255. (Pdb) step
  256. --Return--
  257. > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[0]>(5)skip_module()->None
  258. -> mod.foo_pony(callback)
  259. (Pdb) step
  260. > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[1]>(10)<module>()
  261. -> pass # provides something to "step" to
  262. (Pdb) continue
  263. """
  264. def test_pdb_continue_in_bottomframe():
  265. """Test that "continue" and "next" work properly in bottom frame (issue #5294).
  266. >>> def test_function():
  267. ... import pdb, sys; inst = pdb.Pdb()
  268. ... inst.set_trace()
  269. ... inst.botframe = sys._getframe() # hackery to get the right botframe
  270. ... print(1)
  271. ... print(2)
  272. ... print(3)
  273. ... print(4)
  274. First, need to clear bdb state that might be left over from previous tests.
  275. Otherwise, the new breakpoints might get assigned different numbers.
  276. >>> from bdb import Breakpoint
  277. >>> Breakpoint.next = 1
  278. >>> Breakpoint.bplist = {}
  279. >>> Breakpoint.bpbynumber = [None]
  280. >>> with PdbTestInput([
  281. ... 'next',
  282. ... 'break 7',
  283. ... 'continue',
  284. ... 'next',
  285. ... 'continue',
  286. ... 'continue',
  287. ... ]):
  288. ... test_function()
  289. > <doctest test.test_pdb.test_pdb_continue_in_bottomframe[0]>(4)test_function()
  290. -> inst.botframe = sys._getframe() # hackery to get the right botframe
  291. (Pdb) next
  292. > <doctest test.test_pdb.test_pdb_continue_in_bottomframe[0]>(5)test_function()
  293. -> print(1)
  294. (Pdb) break 7
  295. Breakpoint 1 at <doctest test.test_pdb.test_pdb_continue_in_bottomframe[0]>:7
  296. (Pdb) continue
  297. 1
  298. 2
  299. > <doctest test.test_pdb.test_pdb_continue_in_bottomframe[0]>(7)test_function()
  300. -> print(3)
  301. (Pdb) next
  302. 3
  303. > <doctest test.test_pdb.test_pdb_continue_in_bottomframe[0]>(8)test_function()
  304. -> print(4)
  305. (Pdb) continue
  306. 4
  307. """
  308. class ModuleInitTester(unittest.TestCase):
  309. def test_filename_correct(self):
  310. """
  311. In issue 7750, it was found that if the filename has a sequence that
  312. resolves to an escape character in a Python string (such as \t), it
  313. will be treated as the escaped character.
  314. """
  315. # the test_fn must contain something like \t
  316. # on Windows, this will create 'test_mod.py' in the current directory.
  317. # on Unix, this will create '.\test_mod.py' in the current directory.
  318. test_fn = '.\\test_mod.py'
  319. code = 'print("testing pdb")'
  320. with open(test_fn, 'w') as f:
  321. f.write(code)
  322. self.addCleanup(os.remove, test_fn)
  323. cmd = [sys.executable, '-m', 'pdb', test_fn,]
  324. proc = subprocess.Popen(cmd,
  325. stdout=subprocess.PIPE,
  326. stdin=subprocess.PIPE,
  327. stderr=subprocess.STDOUT,
  328. )
  329. stdout, stderr = proc.communicate('quit\n')
  330. self.assertIn(code, stdout, "pdb munged the filename")
  331. def test_main():
  332. from test import test_pdb
  333. test_support.run_doctest(test_pdb, verbosity=True)
  334. test_support.run_unittest(
  335. PdbTestCase,
  336. ModuleInitTester)
  337. if __name__ == '__main__':
  338. test_main()