Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Doc/library/pdb.rst
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,9 @@ access further features, you have to do this yourself:
.. versionadded:: 3.14
Added the *mode* argument.

.. versionchanged:: 3.14
*skip* will be ignored if inline breakpoints like :func:`breakpoint` or :func:`set_trace` are used.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"if ... are used" could be misunderstood to mean that skip will always be ignored if those are ever used.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will changing it to "when ... are used" better? Or we should just use the longer version from the news entry?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think "when .. are used" has the same problem, as does the longer version from the news entry.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inline breakpoints like :func:`breakpoint` or :func:`pdb.set_trace` will always stop the program at calling frame, ignoring the ``skip`` pattern (if any).

Is this better?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then I'll use this for all 3 places :)


.. method:: run(statement, globals=None, locals=None)
runeval(expression, globals=None, locals=None)
runcall(function, *args, **kwds)
Expand Down
5 changes: 5 additions & 0 deletions Doc/whatsnew/3.14.rst
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,11 @@ pdb
the quit and call :func:`sys.exit`, instead of raising :exc:`bdb.BdbQuit`.
(Contributed by Tian Gao in :gh:`124704`.)

* :mod:`pdb` will always stop on calling frames when inline breakpoints like
:func:`breakpoint` or :func:`pdb.set_trace` are used, ignoring the ``skip``
pattern (if any).
(Contributed by Tian Gao in :gh:`130493`.)


pickle
------
Expand Down
9 changes: 6 additions & 3 deletions Lib/bdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,10 +215,13 @@ def dispatch_opcode(self, frame, arg):
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
Expand Down
22 changes: 22 additions & 0 deletions Lib/test/test_pdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -4341,6 +4341,28 @@ def test_quit(self):
# 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.requires_subprocess()
class PdbTestReadline(unittest.TestCase):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
:mod:`pdb` will always stop on calling frames when inline breakpoints like :func:`breakpoint` or :func:`pdb.set_trace` are used, ignoring the ``skip`` pattern (if any).
Loading