Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 01ef1f9

Browse files
GH-89988: Fix memory leak in pickle.Pickler dispatch_table lookup (GH-94298)
1 parent e6391e0 commit 01ef1f9

File tree

3 files changed

+27
-1
lines changed

3 files changed

+27
-1
lines changed

Lib/test/test_pickle.py

+23
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):
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

+3-1
Original file line numberDiff line numberDiff line change
@@ -4761,7 +4761,9 @@ _pickle_Pickler___init___impl(PicklerObject *self, PyObject *file,
47614761
{
47624762
return -1;
47634763
}
4764-
4764+
if (self->dispatch_table != NULL) {
4765+
return 0;
4766+
}
47654767
if (_PyObject_LookupAttr((PyObject *)self, &_Py_ID(dispatch_table),
47664768
&self->dispatch_table) < 0) {
47674769
return -1;

0 commit comments

Comments
 (0)