Skip to content

Commit 91f7914

Browse files
GH-89988: Fix memory leak in pickle.Pickler dispatch_table lookup (GH-94298)
(cherry picked from commit 01ef1f9) Co-authored-by: Kumar Aditya <[email protected]>
1 parent 29fc20c commit 91f7914

File tree

3 files changed

+27
-1
lines changed

3 files changed

+27
-1
lines changed

Lib/test/test_pickle.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,29 @@ def persistent_id(obj):
154154
return obj
155155
check(PersPickler)
156156

157+
@support.cpython_only
158+
def test_custom_pickler_dispatch_table_memleak(self):
159+
# See https://github.com/python/cpython/issues/89988
160+
161+
class Pickler(self.pickler):
162+
def __init__(self, *args, **kwargs):
163+
self.dispatch_table = table
164+
super().__init__(*args, **kwargs)
165+
166+
class DispatchTable:
167+
pass
168+
169+
table = DispatchTable()
170+
pickler = Pickler(io.BytesIO())
171+
self.assertIs(pickler.dispatch_table, table)
172+
table_ref = weakref.ref(table)
173+
self.assertIsNotNone(table_ref())
174+
del pickler
175+
del table
176+
support.gc_collect()
177+
self.assertIsNone(table_ref())
178+
179+
157180
@support.cpython_only
158181
def test_unpickler_reference_cycle(self):
159182
def check(Unpickler):
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix memory leak in :class:`pickle.Pickler` when looking up :attr:`dispatch_table`. Patch by Kumar Aditya.

Modules/_pickle.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4773,7 +4773,9 @@ _pickle_Pickler___init___impl(PicklerObject *self, PyObject *file,
47734773
{
47744774
return -1;
47754775
}
4776-
4776+
if (self->dispatch_table != NULL) {
4777+
return 0;
4778+
}
47774779
if (_PyObject_LookupAttr((PyObject *)self, &_Py_ID(dispatch_table),
47784780
&self->dispatch_table) < 0) {
47794781
return -1;

0 commit comments

Comments
 (0)