Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 09d4c07

Browse filesBrowse files
[3.13] gh-58933: Make pdb return to caller frame correctly when f_trace is not set (GH-118979) (#119007)
gh-58933: Make pdb return to caller frame correctly when f_trace is not set (GH-118979) (cherry picked from commit f526314) Co-authored-by: Tian Gao <gaogaotiantian@hotmail.com>
1 parent 44995aa commit 09d4c07
Copy full SHA for 09d4c07

File tree

3 files changed

+62
-7
lines changed
Filter options

3 files changed

+62
-7
lines changed

‎Lib/bdb.py

Copy file name to clipboardExpand all lines: Lib/bdb.py
+9-7Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,11 @@ def dispatch_return(self, frame, arg):
165165
# The user issued a 'next' or 'until' command.
166166
if self.stopframe is frame and self.stoplineno != -1:
167167
self._set_stopinfo(None, None)
168+
# The previous frame might not have f_trace set, unless we are
169+
# issuing a command that does not expect to stop, we should set
170+
# f_trace
171+
if self.stoplineno != -1:
172+
self._set_caller_tracefunc(frame)
168173
return self.trace_dispatch
169174

170175
def dispatch_exception(self, frame, arg):
@@ -320,15 +325,14 @@ def _set_stopinfo(self, stopframe, returnframe, stoplineno=0, opcode=False):
320325
self.stoplineno = stoplineno
321326
self._set_trace_opcodes(opcode)
322327

323-
def _set_caller_tracefunc(self):
328+
def _set_caller_tracefunc(self, current_frame):
324329
# Issue #13183: pdb skips frames after hitting a breakpoint and running
325330
# step commands.
326331
# Restore the trace function in the caller (that may not have been set
327332
# for performance reasons) when returning from the current frame.
328-
if self.frame_returning:
329-
caller_frame = self.frame_returning.f_back
330-
if caller_frame and not caller_frame.f_trace:
331-
caller_frame.f_trace = self.trace_dispatch
333+
caller_frame = current_frame.f_back
334+
if caller_frame and not caller_frame.f_trace:
335+
caller_frame.f_trace = self.trace_dispatch
332336

333337
# Derived classes and clients can call the following methods
334338
# to affect the stepping state.
@@ -343,12 +347,10 @@ def set_until(self, frame, lineno=None):
343347

344348
def set_step(self):
345349
"""Stop after one line of code."""
346-
self._set_caller_tracefunc()
347350
self._set_stopinfo(None, None)
348351

349352
def set_stepinstr(self):
350353
"""Stop before the next instruction."""
351-
self._set_caller_tracefunc()
352354
self._set_stopinfo(None, None, opcode=True)
353355

354356
def set_next(self, frame):

‎Lib/test/test_pdb.py

Copy file name to clipboardExpand all lines: Lib/test/test_pdb.py
+52Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1453,6 +1453,58 @@ def test_post_mortem():
14531453
"""
14541454

14551455

1456+
def test_pdb_return_to_different_file():
1457+
"""When pdb returns to a different file, it should not skip if f_trace is
1458+
not already set
1459+
1460+
>>> import pprint
1461+
1462+
>>> class A:
1463+
... def __repr__(self):
1464+
... return 'A'
1465+
1466+
>>> def test_function():
1467+
... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
1468+
... pprint.pprint(A())
1469+
1470+
>>> reset_Breakpoint()
1471+
>>> with PdbTestInput([ # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
1472+
... 'b A.__repr__',
1473+
... 'continue',
1474+
... 'return',
1475+
... 'next',
1476+
... 'return',
1477+
... 'return',
1478+
... 'continue',
1479+
... ]):
1480+
... test_function()
1481+
> <doctest test.test_pdb.test_pdb_return_to_different_file[2]>(2)test_function()
1482+
-> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
1483+
(Pdb) b A.__repr__
1484+
Breakpoint 1 at <doctest test.test_pdb.test_pdb_return_to_different_file[1]>:3
1485+
(Pdb) continue
1486+
> <doctest test.test_pdb.test_pdb_return_to_different_file[1]>(3)__repr__()
1487+
-> return 'A'
1488+
(Pdb) return
1489+
--Return--
1490+
> <doctest test.test_pdb.test_pdb_return_to_different_file[1]>(3)__repr__()->'A'
1491+
-> return 'A'
1492+
(Pdb) next
1493+
> ...pprint.py..._safe_repr()
1494+
-> return rep,...
1495+
(Pdb) return
1496+
--Return--
1497+
> ...pprint.py..._safe_repr()->('A'...)
1498+
-> return rep,...
1499+
(Pdb) return
1500+
--Return--
1501+
> ...pprint.py...format()->('A'...)
1502+
-> return...
1503+
(Pdb) continue
1504+
A
1505+
"""
1506+
1507+
14561508
def test_pdb_skip_modules():
14571509
"""This illustrates the simple case of module skipping.
14581510
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Make :mod:`pdb` return to caller frame correctly when ``f_trace`` of the caller frame is not set

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.