This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author pierreglaser
Recipients pierreglaser, pitrou
Date 2020-01-29.23:39:27
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1580341168.06.0.481762102037.issue39492@roundup.psfhosted.org>
In-reply-to
Content
The new Pickler reducer_override mechanism introduced in `Python3.8` generates a reference cycle: for optimization purposes, a the pickler.reducer_override bound method is referenced into the reducer_override attribute of the Pickler's struct. Thus, until as a gc.collect call is performed, both the Pickler and all the elements it pickled (as they are part of its memo), wont be collected.

We should break this cycle a the end of the dump() method.

See reproducer below:
```
import threading
import weakref
import pickle
import io


class MyClass:
    pass


my_object = MyClass()
collect = threading.Event()
_ = weakref.ref(my_object, lambda obj: collect.set())  # noqa


class MyPickler(pickle.Pickler):
    def reducer_override(self, obj):
        return NotImplemented


my_pickler = MyPickler(io.BytesIO())
my_pickler.dump(my_object)
del my_object
del my_pickler

# import gc
# gc.collect()

for i in range(5):
    collected = collect.wait(timeout=0.1)
    if collected:
        print('my_object was successfully collected')
        break
```
History
Date User Action Args
2020-01-29 23:39:28pierreglasersetrecipients: + pierreglaser, pitrou
2020-01-29 23:39:28pierreglasersetmessageid: <1580341168.06.0.481762102037.issue39492@roundup.psfhosted.org>
2020-01-29 23:39:27pierreglaserlinkissue39492 messages
2020-01-29 23:39:27pierreglasercreate