text: # A test suite for pdb; not very comprehensive at the moment.
  
  import doctest
  import imp
  import pdb
  import sys
  import unittest
  import subprocess
  import textwrap
  
  from test import support
  # This little helper class is essential for testing pdb under doctest.
  from test.test_doctest import _FakeInput
  
  
  class PdbTestInput(object):
      """Context manager that makes testing Pdb in doctests easier."""
  
      def __init__(self, input):
          self.input = input
  
      def __enter__(self):
          self.real_stdin = sys.stdin
          sys.stdin = _FakeInput(self.input)
          self.orig_trace = sys.gettrace() if hasattr(sys, 'gettrace') else None
  
      def __exit__(self, *exc):
          sys.stdin = self.real_stdin
          if self.orig_trace:
              sys.settrace(self.orig_trace)
  
  
  def test_pdb_displayhook():
      """This tests the custom displayhook for pdb.
  
      >>> def test_function(foo, bar):
      ...     import pdb; pdb.Pdb(nosigint=True).set_trace()
      ...     pass
  
      >>> with PdbTestInput([
      ...     'foo',
      ...     'bar',
      ...     'for i in range(5): print(i)',
      ...     'continue',
      ... ]):
      ...     test_function(1, None)
      > <doctest test.test_pdb.test_pdb_displayhook[0]>(3)test_function()
      -> pass
      (Pdb) foo
      1
      (Pdb) bar
      (Pdb) for i in range(5): print(i)
      0
      1
      2
      3
      4
      (Pdb) continue
      """
  
  
  def test_pdb_basic_commands():
      """Test the basic commands of pdb.
  
      >>> def test_function_2(foo, bar='default'):
      ...     print(foo)
      ...     for i in range(5):
      ...         print(i)
      ...     print(bar)
      ...     for i in range(10):
      ...         never_executed
      ...     print('after for')
      ...     print('...')
      ...     return foo.upper()
  
      >>> def test_function():
      ...     import pdb; pdb.Pdb(nosigint=True).set_trace()
      ...     ret = test_function_2('baz')
      ...     print(ret)
  
      >>> with PdbTestInput([  # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
      ...     'step',       # entering the function call
      ...     'args',       # display function args
      ...     'list',       # list function source
      ...     'bt',         # display backtrace
      ...     'up',         # step up to test_function()
      ...     'down',       # step down to test_function_2() again
      ...     'next',       # stepping to print(foo)
      ...     'next',       # stepping to the for loop
      ...     'step',       # stepping into the for loop
      ...     'until',      # continuing until out of the for loop
      ...     'next',       # executing the print(bar)
      ...     'jump 8',     # jump over second for loop
      ...     'return',     # return out of function
      ...     'retval',     # display return value
      ...     'continue',
      ... ]):
      ...    test_function()
      > <doctest test.test_pdb.test_pdb_basic_commands[1]>(3)test_function()
      -> ret = test_function_2('baz')
      (Pdb) step
      --Call--
      > <doctest test.test_pdb.test_pdb_basic_commands[0]>(1)test_function_2()
      -> def test_function_2(foo, bar='default'):
      (Pdb) args
      foo = 'baz'
      bar = 'default'
      (Pdb) list
        1  ->     def test_function_2(foo, bar='default'):
        2             print(foo)
        3             for i in range(5):
        4                 print(i)
        5             print(bar)
        6             for i in range(10):
        7                 never_executed
        8             print('after for')
        9             print('...')
       10             return foo.upper()
      [EOF]
      (Pdb) bt
      ...
        <doctest test.test_pdb.test_pdb_basic_commands[2]>(18)<module>()
      -> test_function()
        <doctest test.test_pdb.test_pdb_basic_commands[1]>(3)test_function()
      -> ret = test_function_2('baz')
      > <doctest test.test_pdb.test_pdb_basic_commands[0]>(1)test_function_2()
      -> def test_function_2(foo, bar='default'):
      (Pdb) up
      > <doctest test.test_pdb.test_pdb_basic_commands[1]>(3)test_function()
      -> ret = test_function_2('baz')
      (Pdb) down
      > <doctest test.test_pdb.test_pdb_basic_commands[0]>(1)test_function_2()
      -> def test_function_2(foo, bar='default'):
      (Pdb) next
      > <doctest test.test_pdb.test_pdb_basic_commands[0]>(2)test_function_2()
      -> print(foo)
      (Pdb) next
      baz
      > <doctest test.test_pdb.test_pdb_basic_commands[0]>(3)test_function_2()
      -> for i in range(5):
      (Pdb) step
      > <doctest test.test_pdb.test_pdb_basic_commands[0]>(4)test_function_2()
      -> print(i)
      (Pdb) until
      0
      1
      2
      3
      4
      > <doctest test.test_pdb.test_pdb_basic_commands[0]>(5)test_function_2()
      -> print(bar)
      (Pdb) next
      default
      > <doctest test.test_pdb.test_pdb_basic_commands[0]>(6)test_function_2()
      -> for i in range(10):
      (Pdb) jump 8
      > <doctest test.test_pdb.test_pdb_basic_commands[0]>(8)test_function_2()
      -> print('after for')
      (Pdb) return
      after for
      ...
      --Return--
      > <doctest test.test_pdb.test_pdb_basic_commands[0]>(10)test_function_2()->'BAZ'
      -> return foo.upper()
      (Pdb) retval
      'BAZ'
      (Pdb) continue
      BAZ
      """
  
  
  def test_pdb_breakpoint_commands():
      """Test basic commands related to breakpoints.
  
      >>> def test_function():
      ...     import pdb; pdb.Pdb(nosigint=True).set_trace()
      ...     print(1)
      ...     print(2)
      ...     print(3)
      ...     print(4)
  
      First, need to clear bdb state that might be left over from previous tests.
      Otherwise, the new breakpoints might get assigned different numbers.
  
      >>> from bdb import Breakpoint
      >>> Breakpoint.next = 1
      >>> Breakpoint.bplist = {}
      >>> Breakpoint.bpbynumber = [None]
  
      Now test the breakpoint commands.  NORMALIZE_WHITESPACE is needed because
      the breakpoint list outputs a tab for the "stop only" and "ignore next"
      lines, which we don't want to put in here.
  
      >>> with PdbTestInput([  # doctest: +NORMALIZE_WHITESPACE
      ...     'break 3',
      ...     'disable 1',
      ...     'ignore 1 10',
      ...     'condition 1 1 < 2',
      ...     'break 4',
      ...     'break 4',
      ...     'break',
      ...     'clear 3',
      ...     'break',
      ...     'condition 1',
      ...     'enable 1',
      ...     'clear 1',
      ...     'commands 2',
      ...     'print 42',
      ...     'end',
      ...     'continue',  # will stop at breakpoint 2 (line 4)
      ...     'clear',     # clear all!
      ...     'y',
      ...     'tbreak 5',
      ...     'continue',  # will stop at temporary breakpoint
      ...     'break',     # make sure breakpoint is gone
      ...     'continue',
      ... ]):
      ...    test_function()
      > <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>(3)test_function()
      -> print(1)
      (Pdb) break 3
      Breakpoint 1 at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:3
      (Pdb) disable 1
      Disabled breakpoint 1 at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:3
      (Pdb) ignore 1 10
      Will ignore next 10 crossings of breakpoint 1.
      (Pdb) condition 1 1 < 2
      New condition set for breakpoint 1.
      (Pdb) break 4
      Breakpoint 2 at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:4
      (Pdb) break 4
      Breakpoint 3 at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:4
      (Pdb) break
      Num Type         Disp Enb   Where
      1   breakpoint   keep no    at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:3
              stop only if 1 < 2
              ignore next 10 hits
      2   breakpoint   keep yes   at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:4
      3   breakpoint   keep yes   at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:4
      (Pdb) clear 3
      Deleted breakpoint 3 at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:4
      (Pdb) break
      Num Type         Disp Enb   Where
      1   breakpoint   keep no    at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:3
              stop only if 1 < 2
              ignore next 10 hits
      2   breakpoint   keep yes   at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:4
      (Pdb) condition 1
      Breakpoint 1 is now unconditional.
      (Pdb) enable 1
      Enabled breakpoint 1 at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:3
      (Pdb) clear 1
      Deleted breakpoint 1 at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:3
      (Pdb) commands 2
      (com) print 42
      (com) end
      (Pdb) continue
      1
      42
      > <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>(4)test_function()
      -> print(2)
      (Pdb) clear
      Clear all breaks? y
      Deleted breakpoint 2 at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:4
      (Pdb) tbreak 5
      Breakpoint 4 at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:5
      (Pdb) continue
      2
      Deleted breakpoint 4 at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:5
      > <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>(5)test_function()
      -> print(3)
      (Pdb) break
      (Pdb) continue
      3
      4
      """
  
  
  def do_nothing():
      pass
  
  def do_something():
      print(42)
  
  def test_list_commands():
      """Test the list and source commands of pdb.
  
      >>> def test_function_2(foo):
      ...     import test.test_pdb
      ...     test.test_pdb.do_nothing()
      ...     'some...'
      ...     'more...'
      ...     'code...'
      ...     'to...'
      ...     'make...'
      ...     'a...'
      ...     'long...'
      ...     'listing...'
      ...     'useful...'
      ...     '...'
      ...     '...'
      ...     return foo
  
      >>> def test_function():
      ...     import pdb; pdb.Pdb(nosigint=True).set_trace()
      ...     ret = test_function_2('baz')
  
      >>> with PdbTestInput([  # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
      ...     'list',      # list first function
      ...     'step',      # step into second function
      ...     'list',      # list second function
      ...     'list',      # continue listing to EOF
      ...     'list 1,3',  # list specific lines
      ...     'list x',    # invalid argument
      ...     'next',      # step to import
      ...     'next',      # step over import
      ...     'step',      # step into do_nothing
      ...     'longlist',  # list all lines
      ...     'source do_something',  # list all lines of function
      ...     'source fooxxx',        # something that doesn't exit
      ...     'continue',
      ... ]):
      ...    test_function()
      > <doctest test.test_pdb.test_list_commands[1]>(3)test_function()
      -> ret = test_function_2('baz')
      (Pdb) list
        1         def test_function():
        2             import pdb; pdb.Pdb(nosigint=True).set_trace()
        3  ->         ret = test_function_2('baz')
      [EOF]
      (Pdb) step
      --Call--
      > <doctest test.test_pdb.test_list_commands[0]>(1)test_function_2()
      -> def test_function_2(foo):
      (Pdb) list
        1  ->     def test_function_2(foo):
        2             import test.test_pdb
        3             test.test_pdb.do_nothing()
        4             'some...'
        5             'more...'
        6             'code...'
        7             'to...'
        8             'make...'
        9             'a...'
       10             'long...'
       11             'listing...'
      (Pdb) list
       12             'useful...'
       13             '...'
       14             '...'
       15             return foo
      [EOF]
      (Pdb) list 1,3
        1  ->     def test_function_2(foo):
        2             import test.test_pdb
        3             test.test_pdb.do_nothing()
      (Pdb) list x
      *** ...
      (Pdb) next
      > <doctest test.test_pdb.test_list_commands[0]>(2)test_function_2()
      -> import test.test_pdb
      (Pdb) next
      > <doctest test.test_pdb.test_list_commands[0]>(3)test_function_2()
      -> test.test_pdb.do_nothing()
      (Pdb) step
      --Call--
      > ...test_pdb.py(...)do_nothing()
      -> def do_nothing():
      (Pdb) longlist
      ...  ->     def do_nothing():
      ...             pass
      (Pdb) source do_something
      ...         def do_something():
      ...             print(42)
      (Pdb) source fooxxx
      *** ...
      (Pdb) continue
      """
  
  
  def test_post_mortem():
      """Test post mortem traceback debugging.
  
      >>> def test_function_2():
      ...     try:
      ...         1/0
      ...     finally:
      ...         print('Exception!')
  
      >>> def test_function():
      ...     import pdb; pdb.Pdb(nosigint=True).set_trace()
      ...     test_function_2()
      ...     print('Not reached.')
  
      >>> with PdbTestInput([  # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
      ...     'next',      # step over exception-raising call
      ...     'bt',        # get a backtrace
      ...     'list',      # list code of test_function()
      ...     'down',      # step into test_function_2()
      ...     'list',      # list code of test_function_2()
      ...     'continue',
      ... ]):
      ...    try:
      ...        test_function()
      ...    except ZeroDivisionError:
      ...        print('Correctly reraised.')
      > <doctest test.test_pdb.test_post_mortem[1]>(3)test_function()
      -> test_function_2()
      (Pdb) next
      Exception!
      ZeroDivisionError: division by zero
      > <doctest test.test_pdb.test_post_mortem[1]>(3)test_function()
      -> test_function_2()
      (Pdb) bt
      ...
        <doctest test.test_pdb.test_post_mortem[2]>(10)<module>()
      -> test_function()
      > <doctest test.test_pdb.test_post_mortem[1]>(3)test_function()
      -> test_function_2()
        <doctest test.test_pdb.test_post_mortem[0]>(3)test_function_2()
      -> 1/0
      (Pdb) list
        1         def test_function():
        2             import pdb; pdb.Pdb(nosigint=True).set_trace()
        3  ->         test_function_2()
        4             print('Not reached.')
      [EOF]
      (Pdb) down
      > <doctest test.test_pdb.test_post_mortem[0]>(3)test_function_2()
      -> 1/0
      (Pdb) list
        1         def test_function_2():
        2             try:
        3  >>             1/0
        4             finally:
        5  ->             print('Exception!')
      [EOF]
      (Pdb) continue
      Correctly reraised.
      """
  
  
  def test_pdb_skip_modules():
      """This illustrates the simple case of module skipping.
  
      >>> def skip_module():
      ...     import string
      ...     import pdb; pdb.Pdb(skip=['stri*'], nosigint=True).set_trace()
      ...     string.capwords('FOO')
  
      >>> with PdbTestInput([
      ...     'step',
      ...     'continue',
      ... ]):
      ...     skip_module()
      > <doctest test.test_pdb.test_pdb_skip_modules[0]>(4)skip_module()
      -> string.capwords('FOO')
      (Pdb) step
      --Return--
      > <doctest test.test_pdb.test_pdb_skip_modules[0]>(4)skip_module()->None
      -> string.capwords('FOO')
      (Pdb) continue
      """
  
  
  # Module for testing skipping of module that makes a callback
  mod = imp.new_module('module_to_skip')
  exec('def foo_pony(callback): x = 1; callback(); return None', mod.__dict__)
  
  
  def test_pdb_skip_modules_with_callback():
      """This illustrates skipping of modules that call into other code.
  
      >>> def skip_module():
      ...     def callback():
      ...         return None
      ...     import pdb; pdb.Pdb(skip=['module_to_skip*'], nosigint=True).set_trace()
      ...     mod.foo_pony(callback)
  
      >>> with PdbTestInput([
      ...     'step',
      ...     'step',
      ...     'step',
      ...     'step',
      ...     'step',
      ...     'continue',
      ... ]):
      ...     skip_module()
      ...     pass  # provides something to "step" to
      > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[0]>(5)skip_module()
      -> mod.foo_pony(callback)
      (Pdb) step
      --Call--
      > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[0]>(2)callback()
      -> def callback():
      (Pdb) step
      > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[0]>(3)callback()
      -> return None
      (Pdb) step
      --Return--
      > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[0]>(3)callback()->None
      -> return None
      (Pdb) step
      --Return--
      > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[0]>(5)skip_module()->None
      -> mod.foo_pony(callback)
      (Pdb) step
      > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[1]>(10)<module>()
      -> pass  # provides something to "step" to
      (Pdb) continue
      """
  
  
  def test_pdb_continue_in_bottomframe():
      """Test that "continue" and "next" work properly in bottom frame (issue #5294).
  
      >>> def test_function():
      ...     import pdb, sys; inst = pdb.Pdb(nosigint=True)
      ...     inst.set_trace()
      ...     inst.botframe = sys._getframe()  # hackery to get the right botframe
      ...     print(1)
      ...     print(2)
      ...     print(3)
      ...     print(4)
  
      >>> with PdbTestInput([  # doctest: +ELLIPSIS
      ...     'next',
      ...     'break 7',
      ...     'continue',
      ...     'next',
      ...     'continue',
      ...     'continue',
      ... ]):
      ...    test_function()
      > <doctest test.test_pdb.test_pdb_continue_in_bottomframe[0]>(4)test_function()
      -> inst.botframe = sys._getframe()  # hackery to get the right botframe
      (Pdb) next
      > <doctest test.test_pdb.test_pdb_continue_in_bottomframe[0]>(5)test_function()
      -> print(1)
      (Pdb) break 7
      Breakpoint ... at <doctest test.test_pdb.test_pdb_continue_in_bottomframe[0]>:7
      (Pdb) continue
      1
      2
      > <doctest test.test_pdb.test_pdb_continue_in_bottomframe[0]>(7)test_function()
      -> print(3)
      (Pdb) next
      3
      > <doctest test.test_pdb.test_pdb_continue_in_bottomframe[0]>(8)test_function()
      -> print(4)
      (Pdb) continue
      4
      """
  
  
  def pdb_invoke(method, arg):
      """Run pdb.method(arg)."""
      import pdb
      getattr(pdb.Pdb(nosigint=True), method)(arg)
  
  
  def test_pdb_run_with_incorrect_argument():
      """Testing run and runeval with incorrect first argument.
  
      >>> pti = PdbTestInput(['continue',])
      >>> with pti:
      ...     pdb_invoke('run', lambda x: x)
      Traceback (most recent call last):
      TypeError: exec() arg 1 must be a string, bytes or code object
  
      >>> with pti:
      ...     pdb_invoke('runeval', lambda x: x)
      Traceback (most recent call last):
      TypeError: eval() arg 1 must be a string, bytes or code object
      """
  
  
  def test_pdb_run_with_code_object():
      """Testing run and runeval with code object as a first argument.
  
      >>> with PdbTestInput(['step','x', 'continue']):  # doctest: +ELLIPSIS
      ...     pdb_invoke('run', compile('x=1', '<string>', 'exec'))
      > <string>(1)<module>()...
      (Pdb) step
      --Return--
      > <string>(1)<module>()->None
      (Pdb) x
      1
      (Pdb) continue
  
      >>> with PdbTestInput(['x', 'continue']):
      ...     x=0
      ...     pdb_invoke('runeval', compile('x+1', '<string>', 'eval'))
      > <string>(1)<module>()->None
      (Pdb) x
      1
      (Pdb) continue
      """
  
  
  class PdbTestCase(unittest.TestCase):
  
      def run_pdb(self, script, commands):
          """Run 'script' lines with pdb and the pdb 'commands'."""
          filename = 'main.py'
          with open(filename, 'w') as f:
              f.write(textwrap.dedent(script))
          self.addCleanup(support.unlink, filename)
          cmd = [sys.executable, '-m', 'pdb', filename]
          stdout = stderr = None
          with subprocess.Popen(cmd, stdout=subprocess.PIPE,
                                     stdin=subprocess.PIPE,
                                     stderr=subprocess.STDOUT,
                                     ) as proc:
              stdout, stderr = proc.communicate(str.encode(commands))
          stdout = stdout and bytes.decode(stdout)
          stderr = stderr and bytes.decode(stderr)
          return stdout, stderr
  
      def test_issue7964(self):
          # open the file as binary so we can force \r\n newline
          with open(support.TESTFN, 'wb') as f:
              f.write(b'print("testing my pdb")\r\n')
          cmd = [sys.executable, '-m', 'pdb', support.TESTFN]
          proc = subprocess.Popen(cmd,
              stdout=subprocess.PIPE,
              stdin=subprocess.PIPE,
              stderr=subprocess.STDOUT,
              )
          self.addCleanup(proc.stdout.close)
          stdout, stderr = proc.communicate(b'quit\n')
          self.assertNotIn(b'SyntaxError', stdout,
                           "Got a syntax error running test script under PDB")
  
      def test_issue13183(self):
          script = """
              from bar import bar
  
              def foo():
                  bar()
  
              def nope():
                  pass
  
              def foobar():
                  foo()
                  nope()
  
              foobar()
          """
          commands = """
              from bar import bar
              break bar
              continue
              step
              step
              quit
          """
          bar = """
              def bar():
                  pass
          """
          with open('bar.py', 'w') as f:
              f.write(textwrap.dedent(bar))
          self.addCleanup(support.unlink, 'bar.py')
          stdout, stderr = self.run_pdb(script, commands)
          self.assertTrue(
              any('main.py(5)foo()->None' in l for l in stdout.splitlines()),
              'Fail to step into the caller after a return')
  
      def test_issue13210(self):
          # invoking "continue" on a non-main thread triggered an exception
          # inside signal.signal
  
          # raises SkipTest if python was built without threads
          support.import_module('threading')
  
          with open(support.TESTFN, 'wb') as f:
              f.write(textwrap.dedent("""
                  import threading
                  import pdb
  
                  def start_pdb():
                      pdb.Pdb().set_trace()
                      x = 1
                      y = 1
  
                  t = threading.Thread(target=start_pdb)
                  t.start()""").encode('ascii'))
          cmd = [sys.executable, '-u', support.TESTFN]
          proc = subprocess.Popen(cmd,
              stdout=subprocess.PIPE,
              stdin=subprocess.PIPE,
              stderr=subprocess.STDOUT,
              )
          self.addCleanup(proc.stdout.close)
          stdout, stderr = proc.communicate(b'cont\n')
          self.assertNotIn('Error', stdout.decode(),
                           "Got an error running test script under PDB")
  
      def tearDown(self):
          support.unlink(support.TESTFN)
  
  
  def load_tests(*args):
      from test import test_pdb
      suites = [unittest.makeSuite(PdbTestCase), doctest.DocTestSuite(test_pdb)]
      return unittest.TestSuite(suites)
  
  
  if __name__ == '__main__':
      unittest.main()
  