diff options
-rw-r--r-- | Lib/test/test_memoryio.py | 7 | ||||
-rw-r--r-- | Modules/_io/bytesio.c | 8 | ||||
-rw-r--r-- | Modules/_io/stringio.c | 8 |
3 files changed, 17 insertions, 6 deletions
diff --git a/Lib/test/test_memoryio.py b/Lib/test/test_memoryio.py index c98c307..0b25283 100644 --- a/Lib/test/test_memoryio.py +++ b/Lib/test/test_memoryio.py @@ -338,6 +338,13 @@ class MemoryTestMixin: self.assertEqual(test1(), buf) self.assertEqual(test2(), buf) + def test_instance_dict_leak(self): + # Test case for issue #6242. + # This will be caught by regrtest.py -R if this leak. + for _ in range(100): + memio = self.ioclass() + memio.foo = 1 + class PyBytesIOTest(MemoryTestMixin, MemorySeekTestMixin, unittest.TestCase): diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c index 7675846..daef78f 100644 --- a/Modules/_io/bytesio.c +++ b/Modules/_io/bytesio.c @@ -609,11 +609,14 @@ bytesio_close(bytesio *self) static void bytesio_dealloc(bytesio *self) { + _PyObject_GC_UNTRACK(self); if (self->buf != NULL) { PyMem_Free(self->buf); self->buf = NULL; } - Py_TYPE(self)->tp_clear((PyObject *)self); + Py_CLEAR(self->dict); + if (self->weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *) self); Py_TYPE(self)->tp_free(self); } @@ -667,7 +670,6 @@ static int bytesio_traverse(bytesio *self, visitproc visit, void *arg) { Py_VISIT(self->dict); - Py_VISIT(self->weakreflist); return 0; } @@ -675,8 +677,6 @@ static int bytesio_clear(bytesio *self) { Py_CLEAR(self->dict); - if (self->weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *)self); return 0; } diff --git a/Modules/_io/stringio.c b/Modules/_io/stringio.c index 84a15be..d773723 100644 --- a/Modules/_io/stringio.c +++ b/Modules/_io/stringio.c @@ -509,11 +509,15 @@ static void stringio_dealloc(stringio *self) { _PyObject_GC_UNTRACK(self); + self->ok = 0; + if (self->buf) { + PyMem_Free(self->buf); + self->buf = NULL; + } Py_CLEAR(self->readnl); Py_CLEAR(self->writenl); Py_CLEAR(self->decoder); - if (self->buf) - PyMem_Free(self->buf); + Py_CLEAR(self->dict); if (self->weakreflist != NULL) PyObject_ClearWeakRefs((PyObject *) self); Py_TYPE(self)->tp_free(self); |