Open mdickinson opened 1 year ago
On a similar note QEventLoop does not clean up asyncio.events._set_running_loop which can cause issue when multiple different event loops are used over time (I have a testing situation where this arises).
Hi @mdickinson, thank you for a detailed repro and analysis. I will try to address this issue in the coming weeks. @MatthieuDartiailh this has been fixed in #71 and present in 0.24.0
Hello, after switching this example from pyside6 to pyqt6, this problem disappears. I don't know if it's a bug in qasync or pyside6. Thanks.
We're seeing an issue where the
close
method of aQSelectorEventLoop
doesn't completely clean up resources associated to that event loop.Reproducer
The following code should reproduce:
When I run the above on my machine, I get:
The expectation / hope was that the number of event loops would be stable.
Diagnosis
Here's a graph showing all the ancestors of one of the leaked
QSelectorEventLoop
objects.Those two
lambda
objects at the top have no referrers (in the sense ofgc.get_referrers
); they're apparently being kept alive by PySide6. Thoselambda
s correspond to these two lines:I believe that if we add the corresponding signal
disconnect
s at event loop close time, then this will fix the above issue.System details
pip
)pip
)Context
In case you're wondering why anyone would be creating
QEventLoop
s repeatedly, the answer is unit testing. We're usingqasync
to provide an asyncio event loop for an embedded IPython kernel to use within a Qt-based application. In our test suite we have many tests that create and then tear down that asyncio event loop, and we were observing test interactions as a result of not being able to cleanly clean up all the resources associated to the event loop. (The Qt application itself is a singleton, of course, so we don't try to clean that up between tests.)