]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-82987: Stop on calling frame unconditionally for inline breakpoints (#130493)
authorTian Gao <gaogaotiantian@hotmail.com>
Tue, 4 Mar 2025 16:35:47 +0000 (11:35 -0500)
committerGitHub <noreply@github.com>
Tue, 4 Mar 2025 16:35:47 +0000 (11:35 -0500)
Doc/library/pdb.rst
Doc/whatsnew/3.14.rst
Lib/bdb.py
Lib/test/test_pdb.py
Misc/NEWS.d/next/Library/2025-02-24-01-49-11.gh-issue-82987.vHfQlG.rst [new file with mode: 0644]

index bdd89d127491a53f231053c23a100b6c24e1b4a2..b31625e6b0082f805efdd41c09f7c2bf5daee43a 100644 (file)
@@ -245,6 +245,10 @@ access further features, you have to do this yourself:
    .. versionadded:: 3.14
       Added the *mode* argument.
 
+   .. versionchanged:: 3.14
+      Inline breakpoints like :func:`breakpoint` or :func:`pdb.set_trace` will
+      always stop the program at calling frame, ignoring the *skip* pattern (if any).
+
    .. method:: run(statement, globals=None, locals=None)
                runeval(expression, globals=None, locals=None)
                runcall(function, *args, **kwds)
index aa802faae50b12f59c9ec656cc238d57f09c7412..7b1a30d5a873aee02dcf3c262543aa6eda513fbf 100644 (file)
@@ -780,6 +780,11 @@ pdb
   the quit and call :func:`sys.exit`, instead of raising :exc:`bdb.BdbQuit`.
   (Contributed by Tian Gao in :gh:`124704`.)
 
+* Inline breakpoints like :func:`breakpoint` or :func:`pdb.set_trace` will
+  always stop the program at calling frame, ignoring the ``skip`` pattern
+  (if any).
+  (Contributed by Tian Gao in :gh:`130493`.)
+
 
 pickle
 ------
index a741628e32a981f09aeabf8dcd49efcd403c86ae..2463cc217c6d7500873b0ec22285510a2576e60c 100644 (file)
@@ -215,10 +215,13 @@ class Bdb:
         If the debugger stops on the current opcode, invoke
         self.user_opcode(). Raise BdbQuit if self.quitting is set.
         Return self.trace_dispatch to continue tracing in this scope.
+
+        Opcode event will always trigger the user callback. For now the only
+        opcode event is from an inline set_trace() and we want to stop there
+        unconditionally.
         """
-        if self.stop_here(frame) or self.break_here(frame):
-            self.user_opcode(frame)
-            if self.quitting: raise BdbQuit
+        self.user_opcode(frame)
+        if self.quitting: raise BdbQuit
         return self.trace_dispatch
 
     # Normally derived classes don't override the following
index 7a99c1db84b4397e33f4cdfd0ec3c098869ecb0c..7ecb8d4cd4d5fa056026792fa60033f811cb4900 100644 (file)
@@ -4342,6 +4342,28 @@ class PdbTestInline(unittest.TestCase):
         # The quit prompt should be printed exactly twice
         self.assertEqual(stdout.count("Quit anyway"), 2)
 
+    def test_set_trace_with_skip(self):
+        """GH-82897
+        Inline set_trace() should break unconditionally. This example is a
+        bit oversimplified, but as `pdb.set_trace()` uses the previous Pdb
+        instance, it's possible that we had a previous pdb instance with
+        skip values when we use `pdb.set_trace()` - it would be confusing
+        to users when such inline breakpoints won't break immediately.
+        """
+        script = textwrap.dedent("""
+            import pdb
+            def foo():
+                x = 40 + 2
+                pdb.Pdb(skip=['__main__']).set_trace()
+            foo()
+        """)
+        commands = """
+            p x
+            c
+        """
+        stdout, _ = self._run_script(script, commands)
+        self.assertIn("42", stdout)
+
 
 @support.force_not_colorized_test_class
 @support.requires_subprocess()
diff --git a/Misc/NEWS.d/next/Library/2025-02-24-01-49-11.gh-issue-82987.vHfQlG.rst b/Misc/NEWS.d/next/Library/2025-02-24-01-49-11.gh-issue-82987.vHfQlG.rst
new file mode 100644 (file)
index 0000000..0cfc7cf
--- /dev/null
@@ -0,0 +1 @@
+Inline breakpoints like :func:`breakpoint` or :func:`pdb.set_trace` will always stop the program at calling frame, ignoring the ``skip`` pattern (if any).