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
test_exceptions_dont_leak fails with Python 3.12 #532
Comments
Hi, What is happening is that the pytest-qt/src/pytestqt/exceptions.py Lines 56 to 68 in d72ae76
Not sure what else could be causing this in your system, I'm afraid. |
Thanks @nicoddemus! I couild try tracing that function perhaps? It's clearly some difference in behaviour between Python 3.11 and Python 3.12, at least on my chroot. Would you be able to add Python 3.12 to the list of Python versions tested in |
It seems like the Python 3.12 behaviour is quite different from the Python 3.11 behaviour. I don't understand enough about PyQt5 and Python 3.12 vs Python 3.11 to know what has caused this. Here's what I tried. I modified the test to read: def test_1(qapp):
global weak_ref
w = MyWidget()
weak_ref = weakref.ref(w)
print("weak_ref in test_1 =", weak_ref())
qapp.postEvent(w, qt_api.QtCore.QEvent(qt_api.QtCore.QEvent.Type.User))
qapp.processEvents()
def test_2(qapp):
assert called
print("weak_ref in test_2 pre-collect =", weak_ref())
gc.collect()
print("weak_ref in test_2 post-collect =", weak_ref())
assert weak_ref() is None
print("weak_ref in test_2 post-assert =", weak_ref())
"""
)
result = testdir.runpytest("--capture=tee-sys")
result.stdout.fnmatch_lines(["*1 failed, 1 passed*"]) This allows me to see how the
But with Python 3.12, I get:
So it seems that the object is not garbage-collected at all. This may be a result of the modified garbage collection behaviour in Python 3.12, but it seems a little bizarre for this to be the case. Perhaps something else is going on? I then tried mimicking the pytest-qt script, but without any calls to qapp or pytest: import gc
import weakref
class MyClass:
def __init__(self):
self.var = 1
weak_ref = None
def func1():
global weak_ref
c = MyClass()
weak_ref = weakref.ref(c)
print("weak_ref in func1 =", weak_ref())
def func2():
print("weak_ref in func2 pre-collect =", weak_ref())
gc.collect()
print("weak_ref in func2 post-collect =", weak_ref())
func1()
func2() and the results are as expected:
with both Python 3.11 and Python 3.12. I then modified it to use pytest: def test_func1():
global weak_ref
c = MyClass()
weak_ref = weakref.ref(c)
assert weak_ref() is not None
def test_func2():
gc.collect()
assert weak_ref() is None and pytest succeeds with both Python 3.11 and Python 3.12. I'm not sure what to suggest from here :( |
Thanks @juliangilbey for the detailed post. I did not realize that we were not testing with Python 3.12 yet. I added testing for CI in 3.12 and the problem exists in all platforms, which will help debug this greatly. Regardless, I just released 4.3.1 which skips this test on Python 3.12, which should at least alleviate your immediate problem. I plan to investigate this in more detail when I have some time. Thanks again. |
I ran this test and inspected the live object with objgraph: https://docs.python.org/3/library/sys.html#sys.last_exc is new in 3.12 |
Awesome @graingert, nailed that right on the head. 😁 |
Oh wow, thanks @graingert; what great detective work! |
Hi! Debian is in the process of migrating to Python 3.12, and we have discovered that one of the tests in pytest-qt fails with Python 3.12. Here is the output of running pytest using Python 3.12 and then Python 3.11. There are lots of warnings, but one failure in the 3.12 tests which passes in the 3.11 tests. These tests are being run in a clean chroot, and the version
qt-4.2.0+repack
is just renamed from the originalqt-4.2.0
(the contents are identical).The text was updated successfully, but these errors were encountered: