diff options
Diffstat (limited to 'Lib/test/test_pdb.py')
-rw-r--r-- | Lib/test/test_pdb.py | 348 |
1 files changed, 343 insertions, 5 deletions
diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 03084e4d12..74253b338f 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -1,9 +1,9 @@ # A test suite for pdb; not very comprehensive at the moment. import doctest -import imp import pdb import sys +import types import unittest import subprocess import textwrap @@ -205,7 +205,8 @@ def test_pdb_breakpoint_commands(): ... 'enable 1', ... 'clear 1', ... 'commands 2', - ... 'print 42', + ... 'p "42"', + ... 'print("42", 7*6)', # Issue 18764 (not about breakpoints) ... 'end', ... 'continue', # will stop at breakpoint 2 (line 4) ... 'clear', # clear all! @@ -252,11 +253,13 @@ def test_pdb_breakpoint_commands(): (Pdb) clear 1 Deleted breakpoint 1 at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:3 (Pdb) commands 2 - (com) print 42 + (com) p "42" + (com) print("42", 7*6) (com) end (Pdb) continue 1 - 42 + '42' + 42 42 > <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>(4)test_function() -> print(2) (Pdb) clear @@ -464,7 +467,7 @@ def test_pdb_skip_modules(): # Module for testing skipping of module that makes a callback -mod = imp.new_module('module_to_skip') +mod = types.ModuleType('module_to_skip') exec('def foo_pony(callback): x = 1; callback(); return None', mod.__dict__) @@ -597,6 +600,311 @@ def test_pdb_run_with_code_object(): (Pdb) continue """ +def test_next_until_return_at_return_event(): + """Test that pdb stops after a next/until/return issued at a return debug event. + + >>> def test_function_2(): + ... x = 1 + ... x = 2 + + >>> def test_function(): + ... import pdb; pdb.Pdb(nosigint=True).set_trace() + ... test_function_2() + ... test_function_2() + ... test_function_2() + ... end = 1 + + >>> with PdbTestInput(['break test_function_2', + ... 'continue', + ... 'return', + ... 'next', + ... 'continue', + ... 'return', + ... 'until', + ... 'continue', + ... 'return', + ... 'return', + ... 'continue']): + ... test_function() + > <doctest test.test_pdb.test_next_until_return_at_return_event[1]>(3)test_function() + -> test_function_2() + (Pdb) break test_function_2 + Breakpoint 1 at <doctest test.test_pdb.test_next_until_return_at_return_event[0]>:1 + (Pdb) continue + > <doctest test.test_pdb.test_next_until_return_at_return_event[0]>(2)test_function_2() + -> x = 1 + (Pdb) return + --Return-- + > <doctest test.test_pdb.test_next_until_return_at_return_event[0]>(3)test_function_2()->None + -> x = 2 + (Pdb) next + > <doctest test.test_pdb.test_next_until_return_at_return_event[1]>(4)test_function() + -> test_function_2() + (Pdb) continue + > <doctest test.test_pdb.test_next_until_return_at_return_event[0]>(2)test_function_2() + -> x = 1 + (Pdb) return + --Return-- + > <doctest test.test_pdb.test_next_until_return_at_return_event[0]>(3)test_function_2()->None + -> x = 2 + (Pdb) until + > <doctest test.test_pdb.test_next_until_return_at_return_event[1]>(5)test_function() + -> test_function_2() + (Pdb) continue + > <doctest test.test_pdb.test_next_until_return_at_return_event[0]>(2)test_function_2() + -> x = 1 + (Pdb) return + --Return-- + > <doctest test.test_pdb.test_next_until_return_at_return_event[0]>(3)test_function_2()->None + -> x = 2 + (Pdb) return + > <doctest test.test_pdb.test_next_until_return_at_return_event[1]>(6)test_function() + -> end = 1 + (Pdb) continue + """ + +def test_pdb_next_command_for_generator(): + """Testing skip unwindng stack on yield for generators for "next" command + + >>> def test_gen(): + ... yield 0 + ... return 1 + ... yield 2 + + >>> def test_function(): + ... import pdb; pdb.Pdb(nosigint=True).set_trace() + ... it = test_gen() + ... try: + ... assert next(it) == 0 + ... next(it) + ... except StopIteration as ex: + ... assert ex.value == 1 + ... print("finished") + + >>> with PdbTestInput(['step', + ... 'step', + ... 'step', + ... 'next', + ... 'next', + ... 'step', + ... 'step', + ... 'continue']): + ... test_function() + > <doctest test.test_pdb.test_pdb_next_command_for_generator[1]>(3)test_function() + -> it = test_gen() + (Pdb) step + > <doctest test.test_pdb.test_pdb_next_command_for_generator[1]>(4)test_function() + -> try: + (Pdb) step + > <doctest test.test_pdb.test_pdb_next_command_for_generator[1]>(5)test_function() + -> assert next(it) == 0 + (Pdb) step + --Call-- + > <doctest test.test_pdb.test_pdb_next_command_for_generator[0]>(1)test_gen() + -> def test_gen(): + (Pdb) next + > <doctest test.test_pdb.test_pdb_next_command_for_generator[0]>(2)test_gen() + -> yield 0 + (Pdb) next + > <doctest test.test_pdb.test_pdb_next_command_for_generator[0]>(3)test_gen() + -> return 1 + (Pdb) step + --Return-- + > <doctest test.test_pdb.test_pdb_next_command_for_generator[0]>(3)test_gen()->1 + -> return 1 + (Pdb) step + StopIteration: 1 + > <doctest test.test_pdb.test_pdb_next_command_for_generator[1]>(6)test_function() + -> next(it) + (Pdb) continue + finished + """ + +def test_pdb_return_command_for_generator(): + """Testing no unwindng stack on yield for generators + for "return" command + + >>> def test_gen(): + ... yield 0 + ... return 1 + ... yield 2 + + >>> def test_function(): + ... import pdb; pdb.Pdb(nosigint=True).set_trace() + ... it = test_gen() + ... try: + ... assert next(it) == 0 + ... next(it) + ... except StopIteration as ex: + ... assert ex.value == 1 + ... print("finished") + + >>> with PdbTestInput(['step', + ... 'step', + ... 'step', + ... 'return', + ... 'step', + ... 'step', + ... 'continue']): + ... test_function() + > <doctest test.test_pdb.test_pdb_return_command_for_generator[1]>(3)test_function() + -> it = test_gen() + (Pdb) step + > <doctest test.test_pdb.test_pdb_return_command_for_generator[1]>(4)test_function() + -> try: + (Pdb) step + > <doctest test.test_pdb.test_pdb_return_command_for_generator[1]>(5)test_function() + -> assert next(it) == 0 + (Pdb) step + --Call-- + > <doctest test.test_pdb.test_pdb_return_command_for_generator[0]>(1)test_gen() + -> def test_gen(): + (Pdb) return + StopIteration: 1 + > <doctest test.test_pdb.test_pdb_return_command_for_generator[1]>(6)test_function() + -> next(it) + (Pdb) step + > <doctest test.test_pdb.test_pdb_return_command_for_generator[1]>(7)test_function() + -> except StopIteration as ex: + (Pdb) step + > <doctest test.test_pdb.test_pdb_return_command_for_generator[1]>(8)test_function() + -> assert ex.value == 1 + (Pdb) continue + finished + """ + +def test_pdb_until_command_for_generator(): + """Testing no unwindng stack on yield for generators + for "until" command if target breakpoing is not reached + + >>> def test_gen(): + ... yield 0 + ... yield 1 + ... yield 2 + + >>> def test_function(): + ... import pdb; pdb.Pdb(nosigint=True).set_trace() + ... for i in test_gen(): + ... print(i) + ... print("finished") + + >>> with PdbTestInput(['step', + ... 'until 4', + ... 'step', + ... 'step', + ... 'continue']): + ... test_function() + > <doctest test.test_pdb.test_pdb_until_command_for_generator[1]>(3)test_function() + -> for i in test_gen(): + (Pdb) step + --Call-- + > <doctest test.test_pdb.test_pdb_until_command_for_generator[0]>(1)test_gen() + -> def test_gen(): + (Pdb) until 4 + 0 + 1 + > <doctest test.test_pdb.test_pdb_until_command_for_generator[0]>(4)test_gen() + -> yield 2 + (Pdb) step + --Return-- + > <doctest test.test_pdb.test_pdb_until_command_for_generator[0]>(4)test_gen()->2 + -> yield 2 + (Pdb) step + > <doctest test.test_pdb.test_pdb_until_command_for_generator[1]>(4)test_function() + -> print(i) + (Pdb) continue + 2 + finished + """ + +def test_pdb_next_command_in_generator_for_loop(): + """The next command on returning from a generator controled by a for loop. + + >>> def test_gen(): + ... yield 0 + ... return 1 + + >>> def test_function(): + ... import pdb; pdb.Pdb(nosigint=True).set_trace() + ... for i in test_gen(): + ... print('value', i) + ... x = 123 + + >>> with PdbTestInput(['break test_gen', + ... 'continue', + ... 'next', + ... 'next', + ... 'next', + ... 'continue']): + ... test_function() + > <doctest test.test_pdb.test_pdb_next_command_in_generator_for_loop[1]>(3)test_function() + -> for i in test_gen(): + (Pdb) break test_gen + Breakpoint 6 at <doctest test.test_pdb.test_pdb_next_command_in_generator_for_loop[0]>:1 + (Pdb) continue + > <doctest test.test_pdb.test_pdb_next_command_in_generator_for_loop[0]>(2)test_gen() + -> yield 0 + (Pdb) next + value 0 + > <doctest test.test_pdb.test_pdb_next_command_in_generator_for_loop[0]>(3)test_gen() + -> return 1 + (Pdb) next + Internal StopIteration: 1 + > <doctest test.test_pdb.test_pdb_next_command_in_generator_for_loop[1]>(3)test_function() + -> for i in test_gen(): + (Pdb) next + > <doctest test.test_pdb.test_pdb_next_command_in_generator_for_loop[1]>(5)test_function() + -> x = 123 + (Pdb) continue + """ + +def test_pdb_next_command_subiterator(): + """The next command in a generator with a subiterator. + + >>> def test_subgenerator(): + ... yield 0 + ... return 1 + + >>> def test_gen(): + ... x = yield from test_subgenerator() + ... return x + + >>> def test_function(): + ... import pdb; pdb.Pdb(nosigint=True).set_trace() + ... for i in test_gen(): + ... print('value', i) + ... x = 123 + + >>> with PdbTestInput(['step', + ... 'step', + ... 'next', + ... 'next', + ... 'next', + ... 'continue']): + ... test_function() + > <doctest test.test_pdb.test_pdb_next_command_subiterator[2]>(3)test_function() + -> for i in test_gen(): + (Pdb) step + --Call-- + > <doctest test.test_pdb.test_pdb_next_command_subiterator[1]>(1)test_gen() + -> def test_gen(): + (Pdb) step + > <doctest test.test_pdb.test_pdb_next_command_subiterator[1]>(2)test_gen() + -> x = yield from test_subgenerator() + (Pdb) next + value 0 + > <doctest test.test_pdb.test_pdb_next_command_subiterator[1]>(3)test_gen() + -> return x + (Pdb) next + Internal StopIteration: 1 + > <doctest test.test_pdb.test_pdb_next_command_subiterator[2]>(3)test_function() + -> for i in test_gen(): + (Pdb) next + > <doctest test.test_pdb.test_pdb_next_command_subiterator[2]>(5)test_function() + -> x = 123 + (Pdb) continue + """ + class PdbTestCase(unittest.TestCase): @@ -617,6 +925,36 @@ class PdbTestCase(unittest.TestCase): stderr = stderr and bytes.decode(stderr) return stdout, stderr + def _assert_find_function(self, file_content, func_name, expected): + file_content = textwrap.dedent(file_content) + + with open(support.TESTFN, 'w') as f: + f.write(file_content) + + expected = None if not expected else ( + expected[0], support.TESTFN, expected[1]) + self.assertEqual( + expected, pdb.find_function(func_name, support.TESTFN)) + + def test_find_function_empty_file(self): + self._assert_find_function('', 'foo', None) + + def test_find_function_found(self): + self._assert_find_function( + """\ + def foo(): + pass + + def bar(): + pass + + def quux(): + pass + """, + 'bar', + ('bar', 4), + ) + def test_issue7964(self): # open the file as binary so we can force \r\n newline with open(support.TESTFN, 'wb') as f: |