Skip to content

Commit ccaa5ea

Browse files
pythonGH-89988: Fix memory leak in pickle.Pickler dispatch_table lookup (pythonGH-94298)
1 parent eb7d354 commit ccaa5ea

File tree

3 files changed

+29
-1
lines changed

3 files changed

+29
-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: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4790,8 +4790,12 @@ _pickle_Pickler___init___impl(PicklerObject *self, PyObject *file,
47904790
return -1;
47914791
}
47924792

4793+
4794+
if (self->dispatch_table != NULL) {
4795+
return 0;
4796+
}
47934797
if (_PyObject_LookupAttrId((PyObject *)self,
4794-
&PyId_dispatch_table, &self->dispatch_table) < 0) {
4798+
&PyId_dispatch_table, &self->dispatch_table) < 0) {
47954799
return -1;
47964800
}
47974801

0 commit comments

Comments
 (0)