-
-
Notifications
You must be signed in to change notification settings - Fork 32.2k
gh-135552: Make the GC clear weakrefs later. #136189
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Clear the weakrefs to unreachable objects after finalizers are called.
I can confirm this PR fixes the gh-132413 issue as well. |
I think this fixes (or mostly fixes) gh-91636 as well. |
🤖 New build scheduled with the buildbot fleet by @nascheme for commit 12f0b5c 🤖 Results will be shown at: https://buildbot.python.org/all/#/grid?branch=refs%2Fpull%2F136189%2Fmerge If you want to schedule another build, you need to add the 🔨 test-with-buildbots label again. |
This introduces refleaks, it seems. One of the leaking tests: |
This is the smallest leaking example I could make so far. Something with
|
Other leaking examples (on Windows): 1. test_logging:import logging
import logging.config
import logging.handlers
from multiprocessing import Queue, Manager
class ConfigDictTest(unittest.TestCase):
def test_multiprocessing_queues_XXX(self):
config = {
'version': 1,
'handlers' : {
'spam' : {
'class': 'logging.handlers.QueueHandler',
'queue': Manager().Queue() , # Leak
# 'queue': Manager().JoinableQueue() # Leak
# 'queue': Queue(), # No leak
},
},
'root': {'handlers': ['spam']}
}
logger = logging.getLogger()
logging.config.dictConfig(config)
while logger.handlers:
h = logger.handlers[0]
logger.removeHandler(h)
h.close() 2. test_interpreters.test_api:import contextlib
import threading
import types
from concurrent import interpreters
def func():
raise Exception('spam!')
@contextlib.contextmanager
def captured_thread_exception():
ctx = types.SimpleNamespace(caught=None)
def excepthook(args):
ctx.caught = args
orig_excepthook = threading.excepthook
threading.excepthook = excepthook
try:
yield ctx
finally:
threading.excepthook = orig_excepthook
class TestInterpreterCall(unittest.TestCase):
def test_call_in_thread_XXX(self):
interp = interpreters.create()
call = (interp._call, interp.call)[1] # 0: No leak, 1: Leak
with captured_thread_exception() as _:
t = threading.Thread(target=call, args=(interp, func, (), {}))
t.start()
t.join() |
Clear the weakrefs to unreachable objects after finalizers are called.
datetime.timedelta
(possibly from datetime's Cdelta_new
) #132413