[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