Bug report
Bug description:
If an OSError subclass sets attributes on self prior to calling OSError.__init__ (or if __init__ is invoked multiple times) references are leaked. If OSError.__init__ is called before setting attributes no references are leaked.
import sys, gc 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) msg = "some error message" filename = "some filename" filename2 = "some filename 2" refcount_msg = sys.getrefcount(msg) refcount_filename = sys.getrefcount(filename) refcount_filename2 = sys.getrefcount(filename2) for _ in range(5): try: raise LeakingOSError(1, msg, filename, filename2) except OSError: pass gc.collect() print(f"msg refcount changed: expected {refcount_msg}, got {sys.getrefcount(msg)}") print(f"filename refcount changed: expected {refcount_filename}, got {sys.getrefcount(filename)}") print(f"filename2 refcount changed: expected {refcount_filename2}, got {sys.getrefcount(filename2)}")
msg refcount changed: expected 4, got 9
filename refcount changed: expected 4, got 9
filename2 refcount changed: expected 4, got 9
This has been discovered in PyAV-Org/PyAV#2283
CPython versions tested on:
CPython main branch
Operating systems tested on:
macOS
Linked PRs
- gh-150988: Fix refleak in
OSErrorwhen attrs are set beforesuper().__init__#150990 - gh-150988: Fix OSError reference leak in oserror_init() #151219
- [3.15] gh-150988: Fix refleak in
OSErrorwhen attrs are set beforesuper().__init__()(GH-150990) #151240 - [3.14] gh-150988: Fix refleak in
OSErrorwhen attrs are set beforesuper().__init__()(GH-150990) #151241 - [3.13] gh-150988: Fix refleak in
OSErrorwhen attrs are set beforesuper().__init__()(GH-150990) #151242