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