From: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> Date: Thu, 14 Jul 2022 16:47:17 +0000 (-0700) Subject: GH-89988: Fix memory leak in pickle.Pickler dispatch_table lookup (GH-94298) X-Git-Tag: v3.11.0b5~80 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=91f791400338673f025897c70da99301c85694c5;p=thirdparty%2FPython%2Fcpython.git GH-89988: Fix memory leak in pickle.Pickler dispatch_table lookup (GH-94298) (cherry picked from commit 01ef1f95dab9c9930ce1a23634a3e5a8331bf3c7) Co-authored-by: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com> --- diff --git a/Lib/test/test_pickle.py b/Lib/test/test_pickle.py index 057af21e71fe..44fdca7a6b16 100644 --- a/Lib/test/test_pickle.py +++ b/Lib/test/test_pickle.py @@ -154,6 +154,29 @@ class PyIdPersPicklerTests(AbstractIdentityPersistentPicklerTests, return obj check(PersPickler) + @support.cpython_only + def test_custom_pickler_dispatch_table_memleak(self): + # See https://github.com/python/cpython/issues/89988 + + class Pickler(self.pickler): + def __init__(self, *args, **kwargs): + self.dispatch_table = table + super().__init__(*args, **kwargs) + + class DispatchTable: + pass + + table = DispatchTable() + pickler = Pickler(io.BytesIO()) + self.assertIs(pickler.dispatch_table, table) + table_ref = weakref.ref(table) + self.assertIsNotNone(table_ref()) + del pickler + del table + support.gc_collect() + self.assertIsNone(table_ref()) + + @support.cpython_only def test_unpickler_reference_cycle(self): def check(Unpickler): diff --git a/Misc/NEWS.d/next/Library/2022-06-26-10-59-15.gh-issue-89988.K8rnmt.rst b/Misc/NEWS.d/next/Library/2022-06-26-10-59-15.gh-issue-89988.K8rnmt.rst new file mode 100644 index 000000000000..811a8d6031e0 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-06-26-10-59-15.gh-issue-89988.K8rnmt.rst @@ -0,0 +1 @@ +Fix memory leak in :class:`pickle.Pickler` when looking up :attr:`dispatch_table`. Patch by Kumar Aditya. diff --git a/Modules/_pickle.c b/Modules/_pickle.c index 23d26f6d608f..b4b1dda199c2 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -4773,7 +4773,9 @@ _pickle_Pickler___init___impl(PicklerObject *self, PyObject *file, { return -1; } - + if (self->dispatch_table != NULL) { + return 0; + } if (_PyObject_LookupAttr((PyObject *)self, &_Py_ID(dispatch_table), &self->dispatch_table) < 0) { return -1;