[3.8] bpo-39492: Fix a reference cycle between reducer_override and a Pickler instance (GH-18266) (#18316)

https://bugs.python.org/issue39492

Automerge-Triggered-By: @pitrou
(cherry picked from commit 0f2f35e)

Co-authored-by: Pierre Glaser <pierreglaser@msn.com>
diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py
index c9f3746..3a8aee4 100644
--- a/Lib/test/pickletester.py
+++ b/Lib/test/pickletester.py
@@ -3497,6 +3497,30 @@
                         ValueError, 'The reducer just failed'):
                     p.dump(h)
 
+    @support.cpython_only
+    def test_reducer_override_no_reference_cycle(self):
+        # bpo-39492: reducer_override used to induce a spurious reference cycle
+        # inside the Pickler object, that could prevent all serialized objects
+        # from being garbage-collected without explicity invoking gc.collect.
+
+        for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
+            with self.subTest(proto=proto):
+                def f():
+                    pass
+
+                wr = weakref.ref(f)
+
+                bio = io.BytesIO()
+                p = self.pickler_class(bio, proto)
+                p.dump(f)
+                new_f = pickle.loads(bio.getvalue())
+                assert new_f == 5
+
+                del p
+                del f
+
+                self.assertIsNone(wr())
+
 
 class AbstractDispatchTableTests(unittest.TestCase):