pyapp-kit / superqt

Missing widgets and components for Qt-python
https://pyapp-kit.github.io/superqt/
BSD 3-Clause "New" or "Revised" License
207 stars 36 forks source link

fix: don't enqueue Worker for deletion in `new_worker_qthread` #211

Closed tlambert03 closed 5 months ago

tlambert03 commented 1 year ago

on a tip from @andy-sweet ... to better match the pattern shown in https://doc.qt.io/qt-6/qthread.html#details

@andy-sweet, let me know if you agree this is all that is needed

andy-sweet commented 1 year ago

The problem with the current change is that the Worker is never deleted (unless the caller does it). As it doesn't have a parent, and there no other objects on the new thread as candidate parents, then we can't rely on Qt's object hierarchy to handle it.

My suggestion was to replace the line you deleted with

thread.finished.connect(worker.deleteLater)

which is consistent with the Qt worker thread example.

By making the connection above, the Qt example binds the lifetime of the Controller to the execution of the thread and thus the lifetime of the worker - i.e. the client of the Controller is responsible for its deletion and that will trigger everything else's (though I don't understand where the QThread is deleted...).

By contrast, this superqt function is more automatic and doesn't require the caller to delete anything. The downside of this approach is that as soon as the worker finishes, the calling thread cannot safely refer to the Worker instance. As this function also connects Worker.finished to QThread.quit and QThread.finished to QThread.deleteLater, the calling thread also cannot safely refer to the QThread instance after that time either. I made a rough diagram of the current code to express potential ordering.

In summary, I think my suggestion doesn't actually help here - it just delays the deletion of the worker.

But a docstring update could be useful to warn the caller about using the returned Worker and QThread instances since their lifetimes are hard to predict.

codecov[bot] commented 1 year ago

Codecov Report

Attention: 1 lines in your changes are missing coverage. Please review.

Comparison is base (60188de) 87.34% compared to head (087de9d) 87.34%.

Files Patch % Lines
src/superqt/utils/_qthreading.py 0.00% 1 Missing :warning:
Additional details and impacted files ```diff @@ Coverage Diff @@ ## main #211 +/- ## ======================================= Coverage 87.34% 87.34% ======================================= Files 46 46 Lines 3334 3334 ======================================= Hits 2912 2912 Misses 422 422 ```

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.