[wxPython-users] A possible XRC bug in wxPython 2.8
Robin Dunn
robin at alldunn.com
Mon May 7 13:10:56 PDT 2007
Eli Golovinsky wrote:
> I've encountered some interesting behavior that I think is a bug.
Yes and no...
>
> The attached file creates a wxFrame and a two custom objects one within
> the other. You can see from the prints that the first time the custom
> object is created, everything is fine and the second time it should be
> created it's not because the DoCreateResource method has been rebound to
> None.
>
> I'm guessing this is some issue in the wrapping code. I've debugged it
> into the wxPyCallbackHelper::findCallback function and the
> PyMethod_Check(method) failed. Apparently None isn't a method :).
When wxPython supports overriding C++ virtual methods like this it has
to jump through some hoops to make it work without problems. Take this
use case:
class MyHtmlWindow(html.HtmlWindow):
def OnLinkClicked(self, linkinfo):
# do something custom here...
super(MyHtmlWindow, self).OnLinkClicked(linkinfo)
The program flow in this case goes something like this:
1. The C++ OnLinkClicked is called, since it is a virtual then the
special one in the wxPyHtmlWindow class is called.
2. The C++ OnLinkClicked looks at the Python instance/class to see if
there is an attribute named "OnLinkClicked" and if it is a method. If
it is then it calls it.
3. The Python OnLinkClicked is called, does it's thing, and then tries
to call the base class' method of the same name.
4. This results in a call to the C++ OnLinkClicked method again, looping
us back to #1.
So to solve this endless recursion problem I had to insert a couple
other steps:
2.5. Before calling the Python method set an attribute with a value of
None in the instance with the same name as the method. Then when step 4
loops back to step 1 and on to 2 then the value retrieved will not be a
method object, so it will call the C++ base class method instead.
5. When the call to the Python method returns then remove the temporary
attribute in the instance.
So in your case when control reaches the call to the nested
DoCreateResource it is still set to None from the call to the outer one.
If there is another way to prevent the wrong recursion, but still allow
intended recursion, then I can switch things to work that way, but I
haven't thought of how to do that yet.
--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!
More information about the wxpython-users
mailing list