Skip to content

Commit 7d27561

Browse files
gh-124703: Do not raise an exception when quitting pdb (#124704)
1 parent a49225c commit 7d27561

File tree

3 files changed

+71
-3
lines changed

3 files changed

+71
-3
lines changed

Lib/pdb.py

+14-3
Original file line numberDiff line numberDiff line change
@@ -1725,6 +1725,19 @@ def do_quit(self, arg):
17251725
17261726
Quit from the debugger. The program being executed is aborted.
17271727
"""
1728+
if self.mode == 'inline':
1729+
while True:
1730+
try:
1731+
reply = input('Quitting pdb will kill the process. Quit anyway? [y/n] ')
1732+
reply = reply.lower().strip()
1733+
except EOFError:
1734+
reply = 'y'
1735+
self.message('')
1736+
if reply == 'y' or reply == '':
1737+
sys.exit(0)
1738+
elif reply.lower() == 'n':
1739+
return
1740+
17281741
self._user_requested_quit = True
17291742
self.set_quit()
17301743
return 1
@@ -1738,9 +1751,7 @@ def do_EOF(self, arg):
17381751
Handles the receipt of EOF as a command.
17391752
"""
17401753
self.message('')
1741-
self._user_requested_quit = True
1742-
self.set_quit()
1743-
return 1
1754+
return self.do_quit(arg)
17441755

17451756
def do_args(self, arg):
17461757
"""a(rgs)

Lib/test/test_pdb.py

+56
Original file line numberDiff line numberDiff line change
@@ -4237,6 +4237,62 @@ def test_checkline_is_not_executable(self):
42374237
self.assertFalse(db.checkline(os_helper.TESTFN, lineno))
42384238

42394239

4240+
@support.requires_subprocess()
4241+
class PdbTestInline(unittest.TestCase):
4242+
@unittest.skipIf(sys.flags.safe_path,
4243+
'PYTHONSAFEPATH changes default sys.path')
4244+
def _run_script(self, script, commands,
4245+
expected_returncode=0,
4246+
extra_env=None):
4247+
self.addCleanup(os_helper.rmtree, '__pycache__')
4248+
filename = 'main.py'
4249+
with open(filename, 'w') as f:
4250+
f.write(textwrap.dedent(script))
4251+
self.addCleanup(os_helper.unlink, filename)
4252+
4253+
commands = textwrap.dedent(commands)
4254+
4255+
cmd = [sys.executable, 'main.py']
4256+
if extra_env is not None:
4257+
env = os.environ | extra_env
4258+
else:
4259+
env = os.environ
4260+
with subprocess.Popen(
4261+
cmd,
4262+
stdout=subprocess.PIPE,
4263+
stdin=subprocess.PIPE,
4264+
stderr=subprocess.PIPE,
4265+
env = {**env, 'PYTHONIOENCODING': 'utf-8'}
4266+
) as proc:
4267+
stdout, stderr = proc.communicate(str.encode(commands))
4268+
stdout = bytes.decode(stdout) if isinstance(stdout, bytes) else stdout
4269+
stderr = bytes.decode(stderr) if isinstance(stderr, bytes) else stderr
4270+
self.assertEqual(
4271+
proc.returncode,
4272+
expected_returncode,
4273+
f"Unexpected return code\nstdout: {stdout}\nstderr: {stderr}"
4274+
)
4275+
return stdout, stderr
4276+
4277+
def test_quit(self):
4278+
script = """
4279+
x = 1
4280+
breakpoint()
4281+
"""
4282+
4283+
commands = """
4284+
quit
4285+
n
4286+
p x + 1
4287+
quit
4288+
y
4289+
"""
4290+
4291+
stdout, stderr = self._run_script(script, commands)
4292+
self.assertIn("2", stdout)
4293+
self.assertIn("Quit anyway", stdout)
4294+
4295+
42404296
@support.requires_subprocess()
42414297
class PdbTestReadline(unittest.TestCase):
42424298
def setUpClass():
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Quitting :mod:`pdb` in ``inline`` mode will emit a confirmation prompt and exit gracefully now, instead of printing an exception traceback.

0 commit comments

Comments
 (0)