Troubleshooting sip assignHelper != NULL assertion

Scott Talbert swt at techie.net
Thu May 28 16:30:53 BST 2020


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?

Thanks,
Scott


More information about the PyQt mailing list