Troubleshooting sip assignHelper != NULL assertion
Scott Talbert
swt at techie.net
Thu May 28 16:52:44 BST 2020
On Thu, 28 May 2020, Phil Thompson wrote:
> On 28/05/2020 16:30, Scott Talbert wrote:
>> On Thu, 28 May 2020, Phil Thompson wrote:
>>
>>>>>> Hi,
>>>>>>
>>>>>> I'm running into the following assertion in wxPython that I don't
>>>>>> quite understand:
>>>>>>
>>>>>> python3: ../../../../sip/siplib/siplib.c:3444: parseResult: Assertion
>>>>>> `assign_helper != NULL' failed.
>>>>>>
>>>>>> This is the relevant C++ class:
>>>>>>
>>>>>> class wxPGWindowList
>>>>>> {
>>>>>> public:
>>>>>> wxPGWindowList(wxWindow* primary, wxWindow* secondary = NULL)
>>>>>> : m_primary(primary)
>>>>>> , m_secondary(secondary)
>>>>>> {
>>>>>> }
>>>>>>
>>>>>> void SetSecondary(wxWindow* secondary) { m_secondary = secondary; }
>>>>>>
>>>>>> wxWindow* GetPrimary() const { return m_primary; }
>>>>>> wxWindow* GetSecondary() const { return m_secondary; }
>>>>>>
>>>>>> wxWindow* m_primary;
>>>>>> wxWindow* m_secondary;
>>>>>> };
>>>>>
>>>>> It doesn't matter what the C++ class looks like, it's the corresponding
>>>>> .sip that would be of interest.
>>>>
>>>> My bad, here it is:
>>>> class wxPGWindowList
>>>> {
>>>> %Docstring
>>>> PGWindowList(primary, secondary=None)
>>>>
>>>> Contains a list of editor windows returned by CreateControls.
>>>> %End
>>>> %TypeHeaderCode
>>>> #include <wx/propgrid/editors.h>
>>>> %End
>>>>
>>>> public:
>>>> wxPGWindowList(
>>>> wxWindow * primary,
>>>> wxWindow * secondary = NULL
>>>> );
>>>>
>>>> void SetSecondary(
>>>> wxWindow * secondary
>>>> );
>>>> %Docstring
>>>> SetSecondary(secondary)
>>>> %End
>>>>
>>>> wxWindow * GetPrimary() const;
>>>> %Docstring
>>>> GetPrimary() -> wx.Window
>>>>
>>>> Gets window of primary editor.
>>>> %End
>>>>
>>>> wxWindow * GetSecondary() const;
>>>> %Docstring
>>>> GetSecondary() -> wx.Window
>>>>
>>>> Gets window of secondary editor.
>>>> %End
>>>>
>>>> public:
>>>>
>>>>
>>>> %Property(name=Primary, get=GetPrimary)
>>>> %Property(name=Secondary, get=GetSecondary, set=SetSecondary)
>>>> }; // end of class wxPGWindowList
>>>>
>>>>
>>>>>> The assertion occurs when trying to return an instance of
>>>>>> wxPGWindowList in a Python method, e.g.:
>>>>>>
>>>>>> def foo():
>>>>>> return wxpg.PGWindowList(a, b)
>>>>>>
>>>>>> From what I can tell, there is no assignment helper assigned by sip
>>>>>> because there is no default constructor? I may be missing something,
>>>>>> but I can't see why a default constructor would be needed.
>>>>>
>>>>> You don't say what version of the sip module you are using but I'm
>>>>> guessing that that assertion is when it's parsing the Python object
>>>>> returned by a re-implementation of a C++ virtual. That doesn't seem to
>>>>> be happening in the above which suggests things aren't happening where
>>>>> you think they are.
>>>>
>>>> sip module version is 4.19.19. You are correct, I oversimplified what
>>>> is actually happening. This is really what is happening:
>>>>
>>>> class LargeImageEditor(wxpg.PGEditor):
>>>> def CreateControls(self, propgrid, property, pos, sz):
>>>> ...
>>>> return wxpg.PGWindowList(self.tc, btn)
>>>>
>>>> Where CreateControls is a C++ virtual, relevant .sip snippet:
>>>>
>>>> virtual
>>>> wxPGWindowList CreateControls(
>>>> wxPropertyGrid * propgrid,
>>>> wxPGProperty * property,
>>>> const wxPoint & pos,
>>>> const wxSize & size
>>>> ) const = 0;
>>>> %Docstring
>>>> CreateControls(propgrid, property, pos, size) -> PGWindowList
>>>>
>>>> Instantiates editor controls.
>>>> %End
>>>
>>> So SIP need to copy the wxPGWindowList from the stack to the heap.
>>> Shouldn't CreateControls return a pointer to the wxPGWindowList?
>>>
>>> Of course SIP should detect this when generating the code rather than rely
>>> on a runtime assertion.
>>
>> That is probably how I would have designed the API, but alas it wasn't
>> done that way. :)
>>
>> Shouldn't a (default) copy constructor be sufficient to copy the
>> wxPGWindowList in this case?
>
> SIP may be being too conservative when determining if there is an implied
> copy ctor. Try adding an explicit copy ctor to the wxPGWindowList .sip file.
I don't think that will be enough, though. SIP seems to only set the
assignment helper if there are *both* a public default constructor and a
public copy constructor, see:
https://www.riverbankcomputing.com/hg/sip/file/d85e9957e726/sipgen/transform.c#l596
Scott
More information about the PyQt
mailing list