Fix PRINT_REDIRECTOR calling into a destroyed LogViewer#593
Open
markomarkovic wants to merge 1 commit into
Open
Fix PRINT_REDIRECTOR calling into a destroyed LogViewer#593markomarkovic wants to merge 1 commit into
markomarkovic wants to merge 1 commit into
Conversation
PRINT_REDIRECTOR is a module-level singleton, so the lambda connected to sigStdoutWrite in prepare_panes accumulated one connection per MainWindow and was never disconnected. Each lambda also closed over self and resolved self.components["log"] late through a dict that MainMixin holds as a class attribute, so it reached whichever LogViewer registered last. Once a LogViewer was destroyed, the next print() called into a deleted C++ object and raised RuntimeError. Connecting the bound method instead lets PyQt drop the connection when the receiver is destroyed.
dde7a06 to
10a2eb0
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
PRINT_REDIRECTOR(a module-level singleton inmain_window.py) connected a lambda tosigStdoutWritefor eachMainWindow. The lambda was never disconnected, closed overself, and resolvedself.components["log"]late through the dictMainMixinholds as a class attribute — so it reached whicheverLogViewerregistered last. Once aLogViewerwas destroyed, the nextprint()called into a deleted C++ object and raisedRuntimeError: wrapped C/C++ object of type LogViewer has been deleted.Connecting the bound method
self.components["log"].appendinstead lets PyQt drop the connection automatically when theLogVieweris destroyed.Testing
Adds
test_print_redirector_released_with_window: destroys a window'sLogViewer, emits on the singleton, and asserts no exception reachessys.excepthook. It fails on the old lambda and passes with the fix.pytest tests/— full suite passes.The latent bug exists on master today; it just isn't exercised until multiple
MainWindows are created and torn down (as the display-modes tests do).Claude AI found and fixed the issue.