PySide Bugzilla Closed for New Bugs

PySide is now a Qt Add-on and uses the Qt Project's JIRA Bug Tracker instead of this Bugzilla instance. This Bugzilla is left for reference purposes.

Bug 1049 - Signals and multiple inheritance causes segfaults
: Signals and multiple inheritance causes segfaults
Status: RESOLVED WONTFIX
Product: PySide
Classification: Unclassified
Component: Shiboken
: 1.0.8
: Macintosh Mac OS
: P2 normal
Assigned To: Marcelo Lira
:
:
:
  Show dependency treegraph
 
Reported: 2011-11-07 18:31 EET by Robert Kern
Modified: 2011-12-28 18:58 EET (History)
9 users (show)

See Also:


Attachments
Crashing example. (819 bytes, text/x-python-script)
2011-11-07 18:31 EET, Robert Kern
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Robert Kern 2011-11-07 18:31:17 EET
Created attachment 444 [details]
Crashing example.

I wanted to make a mixin class that defines a new signal and overrides
resizeEvent() to emit that signal. I derived by mixin from QWidget, thinking
that would be the best place to define the signal and override resizeEvent().
However, this causes a segfault when emitting the signal. When I derive the
mixin from the plain old object type, everything works. See the attached code.

Oddly enough, under PyQt, the object-derived version of the mixin segfaults but
not the QWidget-derived one.
Comment 1 Paulo Alcantara 2011-12-27 00:33:52 EET
Hi Robert,

As QtGui.QFrame is inherited from QtGui.QWidget, the CrashingMixin's __init__()
function should be implemented like this (solution):

class CrashingMixin(QtGui.QWidget):
    my_signal = QtCore.Signal()
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(parent)
        ...
        ...

So the segmentation fault occurred because the parent was left uninitialized
and the signal was emitted ("self.my_signal.emit()") along with a None object
passed as parameter.

So make sure to call QtGui.QWidget.__init(parent) explicitly in the
CrashingMixin's constructor.

You might want to take a look at an interesting recent-closed bug:
http://bugs.pyside.org/show_bug.cgi?id=888.

BTW, thanks for the report!

I'm marking this bug as wontfix for now.
Comment 2 Robert Kern 2011-12-28 16:38:30 EET
I'm not sure I understand. CrashingMixing does not provide an __init__() method
so CrashingSubclass.__init__() is actually QFrame.__init__(). If that does not
provide the proper initialization, I'm not sure what would. I do not want to
provide an __init__() method in the mixin since I am going to be mixing it in
with a variety of widget classes that might have different signatures. I don't
understand why a mixin class that does not need any additional initialization
would need its own constructor.
Comment 3 Paulo Alcantara 2011-12-28 18:58:40 EET
(In reply to comment #2)
> I'm not sure I understand. CrashingMixing does not provide an __init__() method
> so CrashingSubclass.__init__() is actually QFrame.__init__(). If that does not
> provide the proper initialization, I'm not sure what would. I do not want to
> provide an __init__() method in the mixin since I am going to be mixing it in
> with a variety of widget classes that might have different signatures. I don't
> understand why a mixin class that does not need any additional initialization
> would need its own constructor.

First, the example I gave previously, in CrashingMixi.__init() you should call
QtGui.Widget.__init__(self) instead of QtGui.QWidget.__init__(parent). Sorry
for the typo.

Well, I think you shouldn't rely on what Python should/must do for you.

For example, let's assume we have a CrashingSubclass class declared like this:

class CrashingSubclass(CrashingMixin):
    pass

Note: we left CrashingMixin unchanged (without an __init__() method in it)

Thus, when we do "obj = CrashingSubclass()" it won't crash either, that's why
CrashingSubclass doesn't require any parent set to QtGui.QWidget.

Now, let's go back to your example:

We have now CrashingSubclass class declared like this:

class CrashingSubclass(CrashingMixin, QtGui.QFrame):
    pass

Thus, when do "obj = CrashingSubclass()" both CrashingMixin and QtGui.QFrame
constructors will be called, so as QtGui.QFrame inherits from QtGui.QWidget and
there is none parent set to QtGui.QWidget, PySide will treat that associated
object as a Nonetype and then the segfault will occur.