]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-124703: Do not raise an exception when quitting pdb (#124704)
authorTian Gao <gaogaotiantian@hotmail.com>
Mon, 27 Jan 2025 03:29:16 +0000 (22:29 -0500)
committerGitHub <noreply@github.com>
Mon, 27 Jan 2025 03:29:16 +0000 (22:29 -0500)
Lib/pdb.py
Lib/test/test_pdb.py
Misc/NEWS.d/next/Library/2024-09-27-19-21-53.gh-issue-124703.lYTLEv.rst [new file with mode: 0644]

index 10d1923cdad2d67fda786e6c1d9da20f88ed8020..beef74d792250bacd27f0b16d5920cef3cc3f769 100644 (file)
@@ -1725,6 +1725,19 @@ class Pdb(bdb.Bdb, cmd.Cmd):
 
         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
@@ -1738,9 +1751,7 @@ class Pdb(bdb.Bdb, cmd.Cmd):
         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)
index 09601623b29ac1692cdd49a76f54cc0505c477b3..4d371a6e754b96b8f511d9171e2c1e319f3bb51d 100644 (file)
@@ -4237,6 +4237,62 @@ class ChecklineTests(unittest.TestCase):
                 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():
diff --git a/Misc/NEWS.d/next/Library/2024-09-27-19-21-53.gh-issue-124703.lYTLEv.rst b/Misc/NEWS.d/next/Library/2024-09-27-19-21-53.gh-issue-124703.lYTLEv.rst
new file mode 100644 (file)
index 0000000..e55d353
--- /dev/null
@@ -0,0 +1 @@
+Quitting :mod:`pdb` in ``inline`` mode will emit a confirmation prompt and exit gracefully now, instead of printing an exception traceback.