Troubleshooting sip assignHelper != NULL assertion
Phil Thompson
phil at riverbankcomputing.com
Sat May 30 17:38:18 BST 2020
On 28/05/2020 16:52, Scott Talbert wrote:
> 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
Should be fixed in the current repo. SIP v4.19.23 will be released next
week.
Be aware that the fix may expose missing private ctors in other .sip
files - PyQt had two cases.
Thanks,
Phil
More information about the PyQt
mailing list