diff options
author | Tian Gao <gaogaotiantian@hotmail.com> | 2024-07-11 02:54:27 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-11 02:54:27 (GMT) |
commit | 690b9355e00d1ea52020fde3feb4c043a2b214e2 (patch) | |
tree | e83456c4be7bfc1d33ba5fc2f92ea951cbf3e9ef | |
parent | 6557af669899f18f8d123f8e1b6c3380d502c519 (diff) | |
download | cpython-690b9355e00d1ea52020fde3feb4c043a2b214e2.zip cpython-690b9355e00d1ea52020fde3feb4c043a2b214e2.tar.gz cpython-690b9355e00d1ea52020fde3feb4c043a2b214e2.tar.bz2 |
gh-121450: Make inline breakpoints use the most recent pdb instance (#121451)
-rw-r--r-- | Doc/whatsnew/3.14.rst | 10 | ||||
-rw-r--r-- | Lib/bdb.py | 1 | ||||
-rw-r--r-- | Lib/pdb.py | 13 | ||||
-rw-r--r-- | Lib/test/test_pdb.py | 43 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2024-07-06-23-39-38.gh-issue-121450.vGqb3c.rst | 4 |
5 files changed, 70 insertions, 1 deletions
diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index d02c10e..da9b45c 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -114,6 +114,16 @@ pathlib another. (Contributed by Barney Gale in :gh:`73991`.) +pdb +--- + +* Hard-coded breakpoints (:func:`breakpoint` and :func:`pdb.set_trace()`) now + reuse the most recent :class:`~pdb.Pdb` instance that calls + :meth:`~pdb.Pdb.set_trace()`, instead of creating a new one each time. + As a result, all the instance specific data like :pdbcmd:`display` and + :pdbcmd:`commands` are preserved across hard-coded breakpoints. + (Contributed by Tian Gao in :gh:`121450`.) + symtable -------- @@ -369,6 +369,7 @@ class Bdb: If frame is not specified, debugging starts from caller's frame. """ + sys.settrace(None) if frame is None: frame = sys._getframe().f_back self.reset() @@ -306,6 +306,8 @@ class Pdb(bdb.Bdb, cmd.Cmd): _file_mtime_table = {} + _last_pdb_instance = None + def __init__(self, completekey='tab', stdin=None, stdout=None, skip=None, nosigint=False, readrc=True): bdb.Bdb.__init__(self, skip=skip) @@ -359,6 +361,12 @@ class Pdb(bdb.Bdb, cmd.Cmd): self._chained_exceptions = tuple() self._chained_exception_index = 0 + def set_trace(self, frame=None): + Pdb._last_pdb_instance = self + if frame is None: + frame = sys._getframe().f_back + super().set_trace(frame) + def sigint_handler(self, signum, frame): if self.allow_kbdint: raise KeyboardInterrupt @@ -2350,7 +2358,10 @@ def set_trace(*, header=None): an assertion fails). If given, *header* is printed to the console just before debugging begins. """ - pdb = Pdb() + if Pdb._last_pdb_instance is not None: + pdb = Pdb._last_pdb_instance + else: + pdb = Pdb() if header is not None: pdb.message(header) pdb.set_trace(sys._getframe().f_back) diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 5c74455..343e15a 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -2448,6 +2448,49 @@ def test_pdb_show_attribute_and_item(): (Pdb) c """ +# doctest will modify pdb.set_trace during the test, so we need to backup +# the original function to use it in the test +original_pdb_settrace = pdb.set_trace + +def test_pdb_with_inline_breakpoint(): + """Hard-coded breakpoint() calls should invoke the same debugger instance + + >>> def test_function(): + ... x = 1 + ... import pdb; pdb.Pdb().set_trace() + ... original_pdb_settrace() + ... x = 2 + + >>> with PdbTestInput(['display x', + ... 'n', + ... 'n', + ... 'n', + ... 'n', + ... 'undisplay', + ... 'c']): + ... test_function() + > <doctest test.test_pdb.test_pdb_with_inline_breakpoint[0]>(3)test_function() + -> import pdb; pdb.Pdb().set_trace() + (Pdb) display x + display x: 1 + (Pdb) n + > <doctest test.test_pdb.test_pdb_with_inline_breakpoint[0]>(4)test_function() + -> original_pdb_settrace() + (Pdb) n + > <doctest test.test_pdb.test_pdb_with_inline_breakpoint[0]>(4)test_function() + -> original_pdb_settrace() + (Pdb) n + > <doctest test.test_pdb.test_pdb_with_inline_breakpoint[0]>(5)test_function() + -> x = 2 + (Pdb) n + --Return-- + > <doctest test.test_pdb.test_pdb_with_inline_breakpoint[0]>(5)test_function()->None + -> x = 2 + display x: 2 [old: 1] + (Pdb) undisplay + (Pdb) c + """ + def test_pdb_issue_20766(): """Test for reference leaks when the SIGINT handler is set. diff --git a/Misc/NEWS.d/next/Library/2024-07-06-23-39-38.gh-issue-121450.vGqb3c.rst b/Misc/NEWS.d/next/Library/2024-07-06-23-39-38.gh-issue-121450.vGqb3c.rst new file mode 100644 index 0000000..4a65fb7 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-07-06-23-39-38.gh-issue-121450.vGqb3c.rst @@ -0,0 +1,4 @@ +Hard-coded breakpoints (:func:`breakpoint` and :func:`pdb.set_trace()`) now +reuse the most recent ``Pdb`` instance that calls ``Pdb.set_trace()``, +instead of creating a new one each time. As a result, all the instance specific +data like ``display`` and ``commands`` are preserved across Hard-coded breakpoints. |