diff --git a/Lib/bdb.py b/Lib/bdb.py index 50cf2b3f5b3e45..0ed8379bac8c1b 100644 --- a/Lib/bdb.py +++ b/Lib/bdb.py @@ -747,7 +747,7 @@ def clear_all_file_breaks(self, filename): return 'There are no breakpoints in %s' % filename for line in self.breaks[filename]: blist = Breakpoint.bplist[filename, line] - for bp in blist: + for bp in blist[:]: bp.deleteMe() del self.breaks[filename] return None diff --git a/Lib/test/test_bdb.py b/Lib/test/test_bdb.py index f15dae13eb384e..8234705e3ad04f 100644 --- a/Lib/test/test_bdb.py +++ b/Lib/test/test_bdb.py @@ -1232,6 +1232,23 @@ def test_next_to_botframe(self): class TestRegressions(unittest.TestCase): + def test_clear_all_file_breaks_with_multiple_bps_same_line(self): + """Regression test: gh-149015. + clear_all_file_breaks must remove all breakpoints even when + multiple breakpoints share the same (file, line).""" + dbg = Bdb() + src = canonic(__file__) + dbg.set_break(src, 10) + dbg.set_break(src, 10) + dbg.set_break(src, 10) + self.assertEqual(len(Breakpoint.bplist[(src, 10)]), 3) + dbg.clear_all_file_breaks(src) + self.assertNotIn((src, 10), Breakpoint.bplist) + for bp in list(Breakpoint.bpbynumber): + if bp is not None: + bp.deleteMe() + + def test_format_stack_entry_no_lineno(self): # See gh-101517 self.assertIn('Warning: lineno is None', diff --git a/Misc/NEWS.d/next/Library.rst b/Misc/NEWS.d/next/Library.rst new file mode 100644 index 00000000000000..611307c6a92ae8 --- /dev/null +++ b/Misc/NEWS.d/next/Library.rst @@ -0,0 +1,4 @@ +bdb: Fix :meth:`bdb.Bdb.clear_all_file_breaks` to not skip breakpoints when multiple +breakpoints share the same file and line. Patch by Aman Sachan. + +.. bpo-149015.