Skip to content

Commit

Permalink
gh-124703: Do not raise an exception when quitting pdb (#124704)
Browse files Browse the repository at this point in the history
  • Loading branch information
gaogaotiantian authored Jan 27, 2025
1 parent a49225c commit 7d27561
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 3 deletions.
17 changes: 14 additions & 3 deletions Lib/pdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -1725,6 +1725,19 @@ def do_quit(self, arg):
Quit from the debugger. The program being executed is aborted.
"""
if self.mode == 'inline':
while True:
try:
reply = input('Quitting pdb will kill the process. Quit anyway? [y/n] ')
reply = reply.lower().strip()
except EOFError:
reply = 'y'
self.message('')
if reply == 'y' or reply == '':
sys.exit(0)
elif reply.lower() == 'n':
return

self._user_requested_quit = True
self.set_quit()
return 1
Expand All @@ -1738,9 +1751,7 @@ def do_EOF(self, arg):
Handles the receipt of EOF as a command.
"""
self.message('')
self._user_requested_quit = True
self.set_quit()
return 1
return self.do_quit(arg)

def do_args(self, arg):
"""a(rgs)
Expand Down
56 changes: 56 additions & 0 deletions Lib/test/test_pdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -4237,6 +4237,62 @@ def test_checkline_is_not_executable(self):
self.assertFalse(db.checkline(os_helper.TESTFN, lineno))


@support.requires_subprocess()
class PdbTestInline(unittest.TestCase):
@unittest.skipIf(sys.flags.safe_path,
'PYTHONSAFEPATH changes default sys.path')
def _run_script(self, script, commands,
expected_returncode=0,
extra_env=None):
self.addCleanup(os_helper.rmtree, '__pycache__')
filename = 'main.py'
with open(filename, 'w') as f:
f.write(textwrap.dedent(script))
self.addCleanup(os_helper.unlink, filename)

commands = textwrap.dedent(commands)

cmd = [sys.executable, 'main.py']
if extra_env is not None:
env = os.environ | extra_env
else:
env = os.environ
with subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
stdin=subprocess.PIPE,
stderr=subprocess.PIPE,
env = {**env, 'PYTHONIOENCODING': 'utf-8'}
) as proc:
stdout, stderr = proc.communicate(str.encode(commands))
stdout = bytes.decode(stdout) if isinstance(stdout, bytes) else stdout
stderr = bytes.decode(stderr) if isinstance(stderr, bytes) else stderr
self.assertEqual(
proc.returncode,
expected_returncode,
f"Unexpected return code\nstdout: {stdout}\nstderr: {stderr}"
)
return stdout, stderr

def test_quit(self):
script = """
x = 1
breakpoint()
"""

commands = """
quit
n
p x + 1
quit
y
"""

stdout, stderr = self._run_script(script, commands)
self.assertIn("2", stdout)
self.assertIn("Quit anyway", stdout)


@support.requires_subprocess()
class PdbTestReadline(unittest.TestCase):
def setUpClass():
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Quitting :mod:`pdb` in ``inline`` mode will emit a confirmation prompt and exit gracefully now, instead of printing an exception traceback.

0 comments on commit 7d27561

Please sign in to comment.