Details
Description
When a class defines __eq__, a signal on this class will crash immediately when connected.
Example code:
from PySide6 import QtCore from PySide6 import QtWidgets class Main: def setup(self): self.input_dialog = QtWidgets.QInputDialog() print('before', flush=True) self.input_dialog.accepted.connect(self.input_accepted) print('after', flush=True) def input_accepted(self): pass def __eq__(self, other): return super().__eq__(other) # def __hash__(self): return id(self) def main(): application = QtWidgets.QApplication([]) main_object = Main() main_object.setup() QtCore.QTimer.singleShot(0, application.quit) application.exec_() if __name__ == "__main__": main()
When we also define a __hash__ function, everything works, again.
What happens?
In the implementation, PyObject_Hash is called, both on the signal function and on the class instance.
The class instance by default is hashable by PyObject s default, but when __eq__ gets explicitly
defined, the default __hash__ is gone.
The second hash call then creates an undetected error, which in turn has the effect that new types
cannot be created, and we segfault.
Solution: We don't call __hash__ a second time, but use the object address directly.
That has no negative effect on the hash function since random plus some offset remains random.
Attachments
Issue Links
- is duplicated by
-
PYSIDE-1801 Signal connection of QObject attribute crashes if __eq__ is reimplemented
- Closed