Troubleshooting sip assignHelper != NULL assertion

Scott Talbert swt at techie.net
Tue Jun 2 16:37:12 BST 2020


On Tue, 2 Jun 2020, Phil Thompson wrote:

> On 02/06/2020 14:03, Scott Talbert wrote:
>> On Tue, 2 Jun 2020, Phil Thompson wrote:
>> 
>>> On 02/06/2020 03:00, Scott Talbert wrote:
>>>> On Mon, 1 Jun 2020, Phil Thompson wrote:
>>>> 
>>>>> On 31/05/2020 17:48, Scott Talbert wrote:
>>>>>> On Sun, 31 May 2020, Phil Thompson wrote:
>>>>>> 
>>>>>>> On 31/05/2020 16:29, Scott Talbert wrote:
>>>>>>>> On Sun, 31 May 2020, Phil Thompson wrote:
>>>>>>>> 
>>>>>>>>> On 31/05/2020 01:23, Scott Talbert wrote:
>>>>>>>>>> On Sat, 30 May 2020, Phil Thompson wrote:
>>>>>>>>>> 
>>>>>>>>>>> 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 for the quick fix.
>>>>>>>>>> 
>>>>>>>>>> However, I think I found a situation with the new code where an 
>>>>>>>>>> assign
>>>>>>>>>> function is getting created where it probably shouldn't be.
>>>>>>>>>> 
>>>>>>>>>> struct wxSplitterRenderParams
>>>>>>>>>> {
>>>>>>>>>>     %Docstring
>>>>>>>>>>         SplitterRenderParams(widthSash_, border_, isSens_)
>>>>>>>>>>
>>>>>>>>>>         This is just a simple struct used as a return value of
>>>>>>>>>>         wxRendererNative::GetSplitterParams().
>>>>>>>>>>     %End
>>>>>>>>>>     %TypeHeaderCode
>>>>>>>>>>         #include <wx/renderer.h>
>>>>>>>>>>     %End
>>>>>>>>>>
>>>>>>>>>>     wxSplitterRenderParams(
>>>>>>>>>>         wxCoord widthSash_,
>>>>>>>>>>         wxCoord border_,
>>>>>>>>>>         bool isSens_
>>>>>>>>>>     );
>>>>>>>>>>
>>>>>>>>>>     const wxCoord border;
>>>>>>>>>>
>>>>>>>>>>     const bool isHotSensitive;
>>>>>>>>>>
>>>>>>>>>>     const wxCoord widthSash;
>>>>>>>>>> 
>>>>>>>>>> };  // end of class wxSplitterRenderParams
>>>>>>>>>> 
>>>>>>>>>> This results in:
>>>>>>>>>> 
>>>>>>>>>> ../../../../sip/cpp/sip_corewxSplitterRenderParams.cpp: In 
>>>>>>>>>> function
>>>>>>>>>> ‘void assign_wxSplitterRenderParams(void*, Py_ssize_t, void*)’:
>>>>>>>>>> ../../../../sip/cpp/sip_corewxSplitterRenderParams.cpp:31:125: 
>>>>>>>>>> error:
>>>>>>>>>> use of deleted function ‘wxSplitterRenderParams&
>>>>>>>>>> wxSplitterRenderParams::operator=(const wxSplitterRenderParams&)’
>>>>>>>>>>    31 |     reinterpret_cast< ::wxSplitterRenderParams
>>>>>>>>>> *>(sipDst)[sipDstIdx] = *reinterpret_cast< 
>>>>>>>>>> ::wxSplitterRenderParams
>>>>>>>>>> *>(sipSrc);
>>>>>>>>>>       | ^
>>>>>>>>>> In file included from 
>>>>>>>>>> ../../../../sip/cpp/sip_corewxSplitterRenderParams.cpp:12:
>>>>>>>>>> ../../../../../Phoenix/ext/wxWidgets/include/wx/renderer.h:97:25:
>>>>>>>>>> note: ‘wxSplitterRenderParams& 
>>>>>>>>>> wxSplitterRenderParams::operator=(const
>>>>>>>>>> wxSplitterRenderParams&)’ is implicitly deleted because the 
>>>>>>>>>> default
>>>>>>>>>> definition would be ill-formed:
>>>>>>>>>>    97 | struct WXDLLIMPEXP_CORE wxSplitterRenderParams
>>>>>>>>>>       |                         ^~~~~~~~~~~~~~~~~~~~~~
>>>>>>>>>> ../../../../../Phoenix/ext/wxWidgets/include/wx/renderer.h:97:25:
>>>>>>>>>> error: non-static const member ‘const wxCoord
>>>>>>>>>> wxSplitterRenderParams::widthSash’, cannot use default assignment
>>>>>>>>>> operator
>>>>>>>>>> ../../../../../Phoenix/ext/wxWidgets/include/wx/renderer.h:97:25:
>>>>>>>>>> error: non-static const member ‘const wxCoord
>>>>>>>>>> wxSplitterRenderParams::border’, cannot use default assignment
>>>>>>>>>> operator
>>>>>>>>>> ../../../../../Phoenix/ext/wxWidgets/include/wx/renderer.h:97:25:
>>>>>>>>>> error: non-static const member ‘const bool
>>>>>>>>>> wxSplitterRenderParams::isHotSensitive’, cannot use default 
>>>>>>>>>> assignment
>>>>>>>>>> operator
>>>>>>>>> 
>>>>>>>>> Yes, that's what I meant by missing private copy ctors. SIP cannot 
>>>>>>>>> accurately determine whether a copy ctor is available unless it 
>>>>>>>>> knows everything about the C++ class (including private members and 
>>>>>>>>> their types), but SIP is not a full C++ parser (and never will be). 
>>>>>>>>> Therefore you need to declare a private copy ctor in the .sip file 
>>>>>>>>> to correct the assumption that there is a public copy ctor 
>>>>>>>>> available. In the future I may add a class annotation to achieve 
>>>>>>>>> the same thing.
>>>>>>>> 
>>>>>>>> Thanks, I understand that now.  :)  After declaring a private copy
>>>>>>>> ctor in the above .sip file, I'm now getting this:
>>>>>>>> 
>>>>>>>> ../../../../sip/cpp/sip_corewxDelegateRendererNative.cpp: In 
>>>>>>>> function
>>>>>>>> ‘PyObject* 
>>>>>>>> meth_wxDelegateRendererNative_GetSplitterParams(PyObject*,
>>>>>>>> PyObject*, PyObject*)’:
>>>>>>>> ../../../../sip/cpp/sip_corewxDelegateRendererNative.cpp:1360:38:
>>>>>>>> error: taking address of rvalue [-fpermissive]
>>>>>>>>  1360 |             sipRes = &(sipSelfWasArg ? sipCpp->
>>>>>>>> ::wxDelegateRendererNative::GetSplitterParams(win) :
>>>>>>>> sipCpp->GetSplitterParams(win));
>>>>>>>>       |
>>>>>>>> ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>>>>>> 
>>>>>>>> So, since SIP can't copy the wxSplitterRenderParams, it is trying to
>>>>>>>> return a reference to the original one, but it seems that doesn't
>>>>>>>> work?
>>>>>>> 
>>>>>>> So what does the .sip file for wxDelegateRenderNative look like?
>>>>>> 
>>>>>> It's a bit long, so attached.
>>>>> 
>>>>> Can you try the current repo.
>>>>> 
>>>>> When you are happy I'll release v4.19.23.
>>>> 
>>>> Unfortunately, I'm still running into trouble with this
>>>> wxSplitterRenderParams class.  This is what I get now:
>>>> 
>>>> ../../../../sip/cpp/sip_corewxRendererNative.cpp: In function
>>>> ‘PyObject* meth_wxRendererNative_GetSplitterParams(PyObject*,
>>>> PyObject*, PyObject*)’:
>>>> ../../../../sip/cpp/sip_corewxRendererNative.cpp:1464:52: error: use
>>>> of deleted function ‘wxSplitterRenderParams&
>>>> wxSplitterRenderParams::operator=(wxSplitterRenderParams&&)’
>>>>  1464 |             *sipRes = sipCpp->GetSplitterParams(win);
>>>>       |                                                    ^
>>>> In file included from 
>>>> ../../../../sip/cpp/sip_corewxRendererNative.cpp:12:
>>>> ../../../../../Phoenix/ext/wxWidgets/include/wx/renderer.h:97:25:
>>>> note: ‘wxSplitterRenderParams&
>>>> wxSplitterRenderParams::operator=(wxSplitterRenderParams&&)’ is
>>>> implicitly deleted because the default definition would be ill-formed:
>>>>    97 | struct WXDLLIMPEXP_CORE wxSplitterRenderParams
>>>>       |                         ^~~~~~~~~~~~~~~~~~~~~~
>>>> ../../../../../Phoenix/ext/wxWidgets/include/wx/renderer.h:97:25:
>>>> error: non-static const member ‘const wxCoord
>>>> wxSplitterRenderParams::widthSash’, cannot use default assignment
>>>> operator
>>>> ../../../../../Phoenix/ext/wxWidgets/include/wx/renderer.h:97:25:
>>>> error: non-static const member ‘const wxCoord
>>>> wxSplitterRenderParams::border’, cannot use default assignment
>>>> operator
>>>> ../../../../../Phoenix/ext/wxWidgets/include/wx/renderer.h:97:25:
>>>> error: non-static const member ‘const bool
>>>> wxSplitterRenderParams::isHotSensitive’, cannot use default assignment
>>>> operator
>>>> ../../../../sip/cpp/sip_corewxRendererNative.cpp: In function
>>>> ‘PyObject* meth_wxRendererNative_GetVersion(PyObject*, PyObject*)’:
>>>> ../../../../sip/cpp/sip_corewxRendererNative.cpp:1508:42: error: use
>>>> of deleted function ‘wxRendererVersion&
>>>> wxRendererVersion::operator=(wxRendererVersion&&)’
>>>>  1508 |             *sipRes = sipCpp->GetVersion();
>>>>       |                                          ^
>>>> In file included from 
>>>> ../../../../sip/cpp/sip_corewxRendererNative.cpp:12:
>>>> ../../../../../Phoenix/ext/wxWidgets/include/wx/renderer.h:141:25:
>>>> note: ‘wxRendererVersion&
>>>> wxRendererVersion::operator=(wxRendererVersion&&)’ is implicitly
>>>> deleted because the default definition would be ill-formed:
>>>>   141 | struct WXDLLIMPEXP_CORE wxRendererVersion
>>>>       |                         ^~~~~~~~~~~~~~~~~
>>>> ../../../../../Phoenix/ext/wxWidgets/include/wx/renderer.h:141:25:
>>>> error: non-static const member ‘const int wxRendererVersion::version’,
>>>> cannot use default assignment operator
>>>> ../../../../../Phoenix/ext/wxWidgets/include/wx/renderer.h:141:25:
>>>> error: non-static const member ‘const int wxRendererVersion::age’,
>>>> cannot use default assignment operator
>>>> 
>>>> 
>>>> I looked at what SIP 4.19.19 generated for
>>>> sip_corewxRendererNative.cpp, and this is what it did:
>>>> 
>>>> sipRes = new ::wxSplitterRenderParams(sipCpp->GetSplitterParams(win));
>>>> 
>>>> So, it seems the wxSplitterRenderParams class does actually have an
>>>> implicit copy constructor that works.  So, it doesn't have an
>>>> assignment operator but DOES have a copy constructor.
>>> 
>>> So if you take out the declaration of the private copy ctor from the .sip 
>>> file...
>> 
>> I did try that way as well, but in that case I get:
>> 
>> ../../../../sip/cpp/sip_corewxSplitterRenderParams.cpp: In function
>> ‘void assign_wxSplitterRenderParams(void*, Py_ssize_t, void*)’:
>> ../../../../sip/cpp/sip_corewxSplitterRenderParams.cpp:31:125: error:
>> use of deleted function ‘wxSplitterRenderParams&
>> wxSplitterRenderParams::operator=(const wxSplitterRenderParams&)’
>>    31 |     reinterpret_cast< ::wxSplitterRenderParams
>> *>(sipDst)[sipDstIdx] = *reinterpret_cast< ::wxSplitterRenderParams
>> *>(sipSrc);
>>       | ^
>> In file included from 
>> ../../../../sip/cpp/sip_corewxSplitterRenderParams.cpp:12:
>> ../../../../../Phoenix/ext/wxWidgets/include/wx/renderer.h:97:25:
>> note: ‘wxSplitterRenderParams& wxSplitterRenderParams::operator=(const
>> wxSplitterRenderParams&)’ is implicitly deleted because the default
>> definition would be ill-formed:
>>    97 | struct WXDLLIMPEXP_CORE wxSplitterRenderParams
>>       |                         ^~~~~~~~~~~~~~~~~~~~~~
>> ../../../../../Phoenix/ext/wxWidgets/include/wx/renderer.h:97:25:
>> error: non-static const member ‘const wxCoord
>> wxSplitterRenderParams::widthSash’, cannot use default assignment
>> operator
>> ../../../../../Phoenix/ext/wxWidgets/include/wx/renderer.h:97:25:
>> error: non-static const member ‘const wxCoord
>> wxSplitterRenderParams::border’, cannot use default assignment
>> operator
>> ../../../../../Phoenix/ext/wxWidgets/include/wx/renderer.h:97:25:
>> error: non-static const member ‘const bool
>> wxSplitterRenderParams::isHotSensitive’, cannot use default assignment
>> operator
>
> ...so follow the same logic as the copy ctor and define a private assignment 
> operator.

Right, okay.  Adding some private assignment ops allowed me to get a bit 
further.  Now I'm running into a problem in a different area.

../../../../sip/cpp/sip_gridcmodule.cpp: In function ‘void 
sipVH__grid_11(sip_gilstate_t, sipVirtErrorHandlerFunc, sipSimpleWrapper*, 
PyObject*, wxDC&, const wxRect&, const wxGridCellAttr&)’:
../../../../sip/cpp/sip_gridcmodule.cpp:1295:199: error: use of deleted 
function ‘wxGridCellAttr::wxGridCellAttr(const wxGridCellAttr&)’
  1295 |     sipCallProcedureMethod(sipGILState, sipErrorHandler, 
sipPySelf, sipMethod, "DNN", &dc, sipType_wxDC, SIP_NULLPTR, new 
::wxRect(rectCell), sipType_wxRect, SIP_NULLPTR, new 
::wxGridCellAttr(attr), sipType_wxGridCellAttr, SIP_NULLPTR);
       | 
^
In file included from 
../../../../../Phoenix/ext/wxWidgets/include/wx/wx.h:14,
                  from ../../../../wx/include/wxPython/wxpy_api.h:41,
                  from ../../../../sip/cpp/sipAPI_grid.h:2373,
                  from ../../../../sip/cpp/sip_gridcmodule.cpp:10:
../../../../../Phoenix/ext/wxWidgets/include/wx/generic/grid.h:650:29: 
note: declared here
   650 |     wxDECLARE_NO_COPY_CLASS(wxGridCellAttr);
       |                             ^~~~~~~~~~~~~~
../../../../../Phoenix/ext/wxWidgets/include/wx/defs.h:3009:9: note: in 
definition of macro ‘wxDECLARE_NO_COPY_CLASS’
  3009 |         classname(const classname&) wxMEMBER_DELETE; \
       |         ^~~~~~~~~


wxGridCellAttr's sip file *does* have a private copy constructor:
     wxGridCellAttr(const wxGridCellAttr&);

However, it also has this public copy constructor:
     wxGridCellAttr(
         wxGridCellAttr * attrDefault = NULL
     )   /Transfer/;

Thanks,
Scott


More information about the PyQt mailing list