From 91bb7e0e3f47cdd09af742c62dc56b3e4c193b0c Mon Sep 17 00:00:00 2001 From: Joekrry Date: Tue, 29 Sep 2026 00:09:33 +0100 Subject: [PATCH] gh-158234: Fixed tracemalloc._compare_grouped_stas mutating old group. _compare_grouped_stats called old_group.pop() in a loop which modified the callers dict in place. --- Lib/test/test_tracemalloc.py | 14 ++++++++++++++ Lib/tracemalloc.py | 3 ++- ...-09-28-00-00-00.gh-issue-158234.tracemalloc.rst | 3 +++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2026-09-28-00-00-00.gh-issue-158234.tracemalloc.rst diff --git a/Lib/test/test_tracemalloc.py b/Lib/test/test_tracemalloc.py index ee02fbd16af0c4e..f55528cecfcb5f3 100644 --- a/Lib/test/test_tracemalloc.py +++ b/Lib/test/test_tracemalloc.py @@ -626,6 +626,20 @@ def test_snapshot_group_by_cumulative(self): tracemalloc.Statistic(tb_a_5, 2, 1), ]) + def test_compare_grouped_stats_no_mutation(self): + tb_a = traceback_lineno('a.py', 1) + tb_b = traceback_lineno('b.py', 1) + old = { + tb_a: tracemalloc.Statistic(tb_a, 100, 2), + tb_b: tracemalloc.Statistic(tb_b, 50, 1), + } + new = { + tb_a: tracemalloc.Statistic(tb_a, 200, 3), + } + old_copy = dict(old) + tracemalloc._compare_grouped_stats(old, new) + self.assertEqual(old, old_copy) + def test_trace_format(self): snapshot, snapshot2 = create_snapshots() trace = snapshot.traces[0] diff --git a/Lib/tracemalloc.py b/Lib/tracemalloc.py index cec99c59700fe05..426981ebe97b4de 100644 --- a/Lib/tracemalloc.py +++ b/Lib/tracemalloc.py @@ -119,6 +119,7 @@ def _sort_key(self): def _compare_grouped_stats(old_group, new_group): statistics = [] + old_group = dict(old_group) for traceback, stat in new_group.items(): previous = old_group.pop(traceback, None) if previous is not None: @@ -478,7 +479,7 @@ def _group_by(self, key_type, cumulative): if key_type not in ('traceback', 'filename', 'lineno'): raise ValueError("unknown key_type: %r" % (key_type,)) if cumulative and key_type not in ('lineno', 'filename'): - raise ValueError("cumulative mode cannot by used " + raise ValueError("cumulative mode cannot be used " "with key type %r" % key_type) stats = {} diff --git a/Misc/NEWS.d/next/Library/2026-09-28-00-00-00.gh-issue-158234.tracemalloc.rst b/Misc/NEWS.d/next/Library/2026-09-28-00-00-00.gh-issue-158234.tracemalloc.rst new file mode 100644 index 000000000000000..e4f360e0154217f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-09-28-00-00-00.gh-issue-158234.tracemalloc.rst @@ -0,0 +1,3 @@ +Fix :func:`tracemalloc._compare_grouped_stats` mutating its *old_group* +argument. Also fix a typo in a :mod:`tracemalloc` error message: +"cannot by used" → "cannot be used".