gc_collect() # For PyPy or other GCs.
self.assertEqual(wr(), None)
+ def test_oserror_reinit_leak(self):
+ # gh-150988: Check for memory leak when re-initializing OSError.
+ # Previously, setting OSError attributes in a subclass
+ # before calling super().__init__() leaked memory.
+ class LeakingOSError(OSError):
+ def __init__(self, code, message, filename, filename2):
+ self.strerror = message
+ self.filename = filename
+ self.filename2 = filename2
+ super().__init__(code, message, filename, None, filename2)
+
+ exc = LeakingOSError(1, "some message", "filename.py", "filename2.py")
+ exc.__init__(2, "another message", "filename3.py", "filename4.py")
+
def test_errno_ENOTDIR(self):
# Issue #12802: "not a directory" errors are ENOTDIR even on Windows
with self.assertRaises(OSError) as cm:
return -1;
}
else {
- self->filename = Py_NewRef(filename);
+ Py_XSETREF(self->filename, Py_NewRef(filename));
if (filename2 && filename2 != Py_None) {
- self->filename2 = Py_NewRef(filename2);
+ Py_XSETREF(self->filename2, Py_NewRef(filename2));
}
if (nargs >= 2 && nargs <= 5) {
}
}
}
- self->myerrno = Py_XNewRef(myerrno);
- self->strerror = Py_XNewRef(strerror);
+ Py_XSETREF(self->myerrno, Py_XNewRef(myerrno));
+ Py_XSETREF(self->strerror, Py_XNewRef(strerror));
#ifdef MS_WINDOWS
- self->winerror = Py_XNewRef(winerror);
+ Py_XSETREF(self->winerror, Py_XNewRef(winerror));
#endif
/* Steals the reference to args */