icecream
icecream copied to clipboard
Incompatibility with Qt's PySide
When I use ic instead of print, the widget shows up as a black screen instead of none at all.
#!/usr/bin/env python3
import sys
from icecream import ic
import PySide6
from PySide6 import QtWidgets
from PySide6.QtCore import QLibraryInfo, qVersion
from PySide6.QtWidgets import QMainWindow
from PySide6.QtMultimediaWidgets import QVideoWidget
class MyWindow(QMainWindow):
def __init__(self):
super().__init__()
def showEvent(self, evt):
# If you replace method2 with method1 or method0, no window will appear for QVideoWidget
self.method2()
def method0(self):
self.setWindowTitle('Method 0')
camera_view = QVideoWidget()
camera_view.show()
def method1(self):
self.setWindowTitle('Method 1')
camera_view = QVideoWidget()
print(camera_view)
camera_view.show()
def method2(self):
self.setWindowTitle('Method 2')
camera_view = QVideoWidget()
ic(camera_view)
camera_view.show()
def main():
print('Python {}.{}'.format(sys.version_info[0], sys.version_info[1]))
print(QLibraryInfo.build())
print(f"PySide6 version: {PySide6.__version__}")
app = QtWidgets.QApplication(sys.argv)
window = MyWindow()
window.show()
sys.exit(app.exec())
if __name__ == "__main__":
main()
I suspect that icecream is doing some weird magic that is triggering some function calls that should not have been made.
Bug report on Qt's end: https://bugreports.qt.io/browse/PYSIDE-1866
When constructing a parentless window as shown in the code, it will be destroyed when leaving the function. Apparently the icecream printer keeps a reference somewhere; so the window remains and is shown.
So we have a good idea of what is causing the bug and this seems to imply that icecream is likely to have memory leak problems.
After some testing, I have managed to discover that icecream.py:229 is causing the trouble. The Source.executing method seems to be maintaining a reference to the local variables even its return value is discarded.
I discovered that adding gc.collect() at the end of IceCreamDebugger.__call__ solves the problem.
--- a/icecream/icecream.py 2022-03-21 15:00:17.604475128 -0300
+++ b/icecream/icecream.py 2022-03-21 14:59:57.518886105 -0300
@@ -13,6 +13,7 @@
from __future__ import print_function
+import gc
import ast
import inspect
import pprint
@@ -216,6 +217,7 @@
else: # E.g. ic(1, 2, 3).
passthrough = args
+ gc.collect()
return passthrough
def format(self, *args):
@gjvnq wonderful digging and homework. that's extremely helpful. thank you! 🙏
strange. the fact that gc.collect() fixes the issue means there's a reference cycle somewhere. otherwise the reference gc would have freed the objects
@gjvnq sanity check: you're running your pyside+icecream app with cpython, right? or a different python interpreter?
garbage collection can be computationally expensive. we dont want to run a gc sweep after every ic() call. @alexmojaki any idea where there might be a reference cycle in executing?
I'm running cpython on a macOS 11 machine.
Em ter., 22 de mar. de 2022 15:23, Ansgar Grunseid @.***> escreveu:
@gjvnq https://github.com/gjvnq wonderful digging and homework. that's extremely helpful. thank you! 🙏
strange. the fact that gc.collect() fixes the issue means there's a reference cycle somewhere. otherwise the reference gc would have freed the objects
@gjvnq https://github.com/gjvnq sanity check: you're running your pyside+icecream app with cpython, right? or a different python interpreter?
garbage collection can be computationally expensive. we dont want to run a gc sweep after every ic() call. @alexmojaki https://github.com/alexmojaki any idea where there might be a reference cycle in executing?
— Reply to this email directly, view it on GitHub https://github.com/gruns/icecream/issues/118#issuecomment-1075476534, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAXIYHEHUJBOVZ53QPCEVMTVBIF2JANCNFSM5RFAZNNQ . You are receiving this because you were mentioned.Message ID: @.***>