-
-
Notifications
You must be signed in to change notification settings - Fork 343
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
SystemError in guest mode when cancelling finished scope #1576
Comments
Maybe you need to set https://doc.qt.io/qt-5/qguiapplication.html#quitOnLastWindowClosed-prop |
It's different, but I'm not sure it's better. :] Just to be clear, I don't see this as an issue for me. It's easy enough to disconnect the signal. But, I generally expect that I shouldn't be able to generate stuff like Outcome: Error(SystemError('<built-in method send of coroutine object at 0x7f28d1fb3340> returned NULL without setting an error'))
StopIteration: 1
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/altendky/repos/trio/trio/_core/_ki.py", line 159, in wrapper
locals()[LOCALS_KEY_KI_PROTECTION_ENABLED] = enabled
SystemError: <built-in function locals> returned a result with an error set
SystemError: <built-in method send of coroutine object at 0x7f28d1fb3340> returned NULL without setting an error Source with `app.setQuitOnLastWindowClosed(False)`import trio
import sys
from outcome import Error
import traceback
# Can't use PySide2 currently because of
# https://bugreports.qt.io/projects/PYSIDE/issues/PYSIDE-1313
from PyQt5 import QtCore, QtWidgets
async def mine():
global cscope
widget = QtWidgets.QWidget()
with trio.CancelScope() as cscope:
app.lastWindowClosed.connect(cscope.cancel)
widget.show()
return 1
app = QtWidgets.QApplication(sys.argv)
app.setQuitOnLastWindowClosed(False)
# This is substantially faster than using a signal... for some reason Qt
# signal dispatch is really slow (and relies on events underneath anyway, so
# this is strictly less work)
REENTER_EVENT = QtCore.QEvent.Type(QtCore.QEvent.registerEventType())
class ReenterEvent(QtCore.QEvent):
pass
class Reenter(QtCore.QObject):
def event(self, event):
event.fn()
return False
reenter = Reenter()
def run_sync_soon_threadsafe(fn):
event = ReenterEvent(REENTER_EVENT)
event.fn = fn
app.postEvent(reenter, event)
def done_callback(outcome):
print(f"Outcome: {outcome}")
if isinstance(outcome, Error):
exc = outcome.error
traceback.print_exception(type(exc), exc, exc.__traceback__)
app.quit()
trio.lowlevel.start_guest_run(
mine,
run_sync_soon_threadsafe=run_sync_soon_threadsafe,
done_callback=done_callback,
)
app.exec_() |
Oh, I missed the |
Hey, I didn't even realize that trio had managed to stay pure Python. :| Anyways, I guess we'll call this 'good' for now. If I get around to following up with PyQt5 I'll post any results back here for reference. I just wrote up a trivial context manager for signal connections to avoid the issue all together. @contextlib.contextmanager
def connection(signal, slot):
this_connection = signal.connect(slot)
try:
yield this_connection
finally:
signal.disconnect(this_connection) |
It definitely looks like PyQt5 / sip has a similar bug as PySide2 / shiboken. I ran your test script under gdb, and did:
Full traceback:
|
Hmm, though the way we're hitting it here is a bit different. I think what's happening is:
|
Full code at the end but here's the 'interesting' snippet that causes trouble when run in guest mode. Tests run with Python 3.8.3 in Linux and 08fca2a.
With just
widget.show()
I get:With
app.lastWindowClosed.connect(cscope.cancel)
andwidget.show()
I get:I've tried to recreate the error without PyQt by just putting the scope cancellation further out but it results in no issues. I thought maybe PyQt was holding onto a reference to a no longer valid object but
global cscope
didn't avoid theSystemError
. The sameSystemError
occurs back to the original commit in #1551, at least there and a few spot checks along the way.I just bothered to follow the why-not-pyside2 link https://bugreports.qt.io/projects/PYSIDE/issues/PYSIDE-1313 and at least the
StopIteration
andSystemError
are similar albeit against a different function call.This isn't any sort of a blocker, just a thing where you have to be careful to disconnect a signal.
Thanks again for guest mode. Someday I'll do something more than a trivial demo with it. :]
Full example source
The text was updated successfully, but these errors were encountered: