bpo-24160: Fix breakpoints persistence across multiple pdb sessions (… · python/cpython@ad442a6 · GitHub
Skip to content

Commit ad442a6

Browse files
authored
bpo-24160: Fix breakpoints persistence across multiple pdb sessions (GH-21989)
1 parent afd1265 commit ad442a6

4 files changed

Lines changed: 144 additions & 13 deletions

File tree

Lib/bdb.py

Lines changed: 26 additions & 3 deletions

Lib/test/test_bdb.py

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,7 @@ class BdbNotExpectedError(BdbException): """Unexpected result."""
7474
dry_run = 0
7575

7676
def reset_Breakpoint():
77-
_bdb.Breakpoint.next = 1
78-
_bdb.Breakpoint.bplist = {}
79-
_bdb.Breakpoint.bpbynumber = [None]
77+
_bdb.Breakpoint.clearBreakpoints()
8078

8179
def info_breakpoints():
8280
bp_list = [bp for bp in _bdb.Breakpoint.bpbynumber if bp]
@@ -951,6 +949,49 @@ def test_clear_at_no_bp(self):
951949
with TracerRun(self) as tracer:
952950
self.assertRaises(BdbError, tracer.runcall, tfunc_import)
953951

952+
def test_load_bps_from_previous_Bdb_instance(self):
953+
reset_Breakpoint()
954+
db1 = Bdb()
955+
fname = db1.canonic(__file__)
956+
db1.set_break(__file__, 1)
957+
self.assertEqual(db1.get_all_breaks(), {fname: [1]})
958+
959+
db2 = Bdb()
960+
db2.set_break(__file__, 2)
961+
db2.set_break(__file__, 3)
962+
db2.set_break(__file__, 4)
963+
self.assertEqual(db1.get_all_breaks(), {fname: [1]})
964+
self.assertEqual(db2.get_all_breaks(), {fname: [1, 2, 3, 4]})
965+
db2.clear_break(__file__, 1)
966+
self.assertEqual(db1.get_all_breaks(), {fname: [1]})
967+
self.assertEqual(db2.get_all_breaks(), {fname: [2, 3, 4]})
968+
969+
db3 = Bdb()
970+
self.assertEqual(db1.get_all_breaks(), {fname: [1]})
971+
self.assertEqual(db2.get_all_breaks(), {fname: [2, 3, 4]})
972+
self.assertEqual(db3.get_all_breaks(), {fname: [2, 3, 4]})
973+
db2.clear_break(__file__, 2)
974+
self.assertEqual(db1.get_all_breaks(), {fname: [1]})
975+
self.assertEqual(db2.get_all_breaks(), {fname: [3, 4]})
976+
self.assertEqual(db3.get_all_breaks(), {fname: [2, 3, 4]})
977+
978+
db4 = Bdb()
979+
db4.set_break(__file__, 5)
980+
self.assertEqual(db1.get_all_breaks(), {fname: [1]})
981+
self.assertEqual(db2.get_all_breaks(), {fname: [3, 4]})
982+
self.assertEqual(db3.get_all_breaks(), {fname: [2, 3, 4]})
983+
self.assertEqual(db4.get_all_breaks(), {fname: [3, 4, 5]})
984+
reset_Breakpoint()
985+
986+
db5 = Bdb()
987+
db5.set_break(__file__, 6)
988+
self.assertEqual(db1.get_all_breaks(), {fname: [1]})
989+
self.assertEqual(db2.get_all_breaks(), {fname: [3, 4]})
990+
self.assertEqual(db3.get_all_breaks(), {fname: [2, 3, 4]})
991+
self.assertEqual(db4.get_all_breaks(), {fname: [3, 4, 5]})
992+
self.assertEqual(db5.get_all_breaks(), {fname: [6]})
993+
994+
954995
class RunTestCase(BaseTestCase):
955996
"""Test run, runeval and set_trace."""
956997

Lib/test/test_pdb.py

Lines changed: 73 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,9 @@ def test_pdb_basic_commands():
213213
BAZ
214214
"""
215215

216+
def reset_Breakpoint():
217+
import bdb
218+
bdb.Breakpoint.clearBreakpoints()
216219

217220
def test_pdb_breakpoint_commands():
218221
"""Test basic commands related to breakpoints.
@@ -227,10 +230,7 @@ def test_pdb_breakpoint_commands():
227230
First, need to clear bdb state that might be left over from previous tests.
228231
Otherwise, the new breakpoints might get assigned different numbers.
229232
230-
>>> from bdb import Breakpoint
231-
>>> Breakpoint.next = 1
232-
>>> Breakpoint.bplist = {}
233-
>>> Breakpoint.bpbynumber = [None]
233+
>>> reset_Breakpoint()
234234
235235
Now test the breakpoint commands. NORMALIZE_WHITESPACE is needed because
236236
the breakpoint list outputs a tab for the "stop only" and "ignore next"
@@ -323,6 +323,72 @@ def test_pdb_breakpoint_commands():
323323
4
324324
"""
325325

326+
def test_pdb_breakpoints_preserved_across_interactive_sessions():
327+
"""Breakpoints are remembered between interactive sessions
328+
329+
>>> reset_Breakpoint()
330+
>>> with PdbTestInput([ # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
331+
... 'import test.test_pdb',
332+
... 'break test.test_pdb.do_something',
333+
... 'break test.test_pdb.do_nothing',
334+
... 'break',
335+
... 'continue',
336+
... ]):
337+
... pdb.run('print()')
338+
> <string>(1)<module>()
339+
(Pdb) import test.test_pdb
340+
(Pdb) break test.test_pdb.do_something
341+
Breakpoint 1 at ...test_pdb.py:...
342+
(Pdb) break test.test_pdb.do_nothing
343+
Breakpoint 2 at ...test_pdb.py:...
344+
(Pdb) break
345+
Num Type Disp Enb Where
346+
1 breakpoint keep yes at ...test_pdb.py:...
347+
2 breakpoint keep yes at ...test_pdb.py:...
348+
(Pdb) continue
349+
350+
>>> with PdbTestInput([ # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
351+
... 'break',
352+
... 'break pdb.find_function',
353+
... 'break',
354+
... 'clear 1',
355+
... 'continue',
356+
... ]):
357+
... pdb.run('print()')
358+
> <string>(1)<module>()
359+
(Pdb) break
360+
Num Type Disp Enb Where
361+
1 breakpoint keep yes at ...test_pdb.py:...
362+
2 breakpoint keep yes at ...test_pdb.py:...
363+
(Pdb) break pdb.find_function
364+
Breakpoint 3 at ...pdb.py:94
365+
(Pdb) break
366+
Num Type Disp Enb Where
367+
1 breakpoint keep yes at ...test_pdb.py:...
368+
2 breakpoint keep yes at ...test_pdb.py:...
369+
3 breakpoint keep yes at ...pdb.py:...
370+
(Pdb) clear 1
371+
Deleted breakpoint 1 at ...test_pdb.py:...
372+
(Pdb) continue
373+
374+
>>> with PdbTestInput([ # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
375+
... 'break',
376+
... 'clear 2',
377+
... 'clear 3',
378+
... 'continue',
379+
... ]):
380+
... pdb.run('print()')
381+
> <string>(1)<module>()
382+
(Pdb) break
383+
Num Type Disp Enb Where
384+
2 breakpoint keep yes at ...test_pdb.py:...
385+
3 breakpoint keep yes at ...pdb.py:...
386+
(Pdb) clear 2
387+
Deleted breakpoint 2 at ...test_pdb.py:...
388+
(Pdb) clear 3
389+
Deleted breakpoint 3 at ...pdb.py:...
390+
(Pdb) continue
391+
"""
326392

327393
def do_nothing():
328394
pass
@@ -699,8 +765,7 @@ def test_next_until_return_at_return_event():
699765
... test_function_2()
700766
... end = 1
701767
702-
>>> from bdb import Breakpoint
703-
>>> Breakpoint.next = 1
768+
>>> reset_Breakpoint()
704769
>>> with PdbTestInput(['break test_function_2',
705770
... 'continue',
706771
... 'return',
@@ -1137,7 +1202,7 @@ def test_pdb_next_command_in_generator_for_loop():
11371202
> <doctest test.test_pdb.test_pdb_next_command_in_generator_for_loop[1]>(3)test_function()
11381203
-> for i in test_gen():
11391204
(Pdb) break test_gen
1140-
Breakpoint 6 at <doctest test.test_pdb.test_pdb_next_command_in_generator_for_loop[0]>:1
1205+
Breakpoint 1 at <doctest test.test_pdb.test_pdb_next_command_in_generator_for_loop[0]>:1
11411206
(Pdb) continue
11421207
> <doctest test.test_pdb.test_pdb_next_command_in_generator_for_loop[0]>(2)test_gen()
11431208
-> yield 0
@@ -1213,6 +1278,7 @@ def test_pdb_issue_20766():
12131278
... print('pdb %d: %s' % (i, sess._previous_sigint_handler))
12141279
... i += 1
12151280
1281+
>>> reset_Breakpoint()
12161282
>>> with PdbTestInput(['continue',
12171283
... 'continue']):
12181284
... test_function()
Lines changed: 1 addition & 0 deletions

0 commit comments

Comments
 (0)