[3.12] gh-77894: Fix a crash when the GC breaks a loop containing a memoryview (GH-123898) (GH-123937)

Now a memoryview object can only be cleared if there are no buffers
that refer it.
(cherry picked from commit a1dbf2ea69)
This commit is contained in:
Serhiy Storchaka 2024-09-11 12:32:39 +03:00 committed by GitHub
parent c6ae90a63c
commit 90e5bd7ed2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 57 additions and 33 deletions

View file

@ -18,6 +18,10 @@ import struct
from test.support import import_helper
class MyObject:
pass
class AbstractMemoryTests:
source_bytes = b"abcdef"
@ -228,8 +232,6 @@ class AbstractMemoryTests:
self.m = memoryview(base)
class MySource(tp):
pass
class MyObject:
pass
# Create a reference cycle through a memoryview object.
# This exercises mbuf_clear().
@ -656,5 +658,26 @@ class OtherTest(unittest.TestCase):
m[0] = MyBool()
self.assertEqual(ba[:8], b'\0'*8)
def test_buffer_reference_loop(self):
m = memoryview(b'abc').__buffer__(0)
o = MyObject()
o.m = m
o.o = o
wr = weakref.ref(o)
del m, o
gc.collect()
self.assertIsNone(wr())
def test_picklebuffer_reference_loop(self):
pb = pickle.PickleBuffer(memoryview(b'abc'))
o = MyObject()
o.pb = pb
o.o = o
wr = weakref.ref(o)
del pb, o
gc.collect()
self.assertIsNone(wr())
if __name__ == "__main__":
unittest.main()