NB this is really a question for Jython devotees but seems to highlight a design difficulty in the language
if I do sthg like this
class XTreeModel( DefaultTreeModel ):
def fireTreeNodesInserted( self, source, path, child_indices, children ):
print "fire nodes inserted"
super( XTreeModel, self ).fireTreeNodesInserted( source, path, child_indices, children )
I get infinite recursion. When I first encountered this I was very puzzled. I still don't understand why the code can't call the Java superclass (baseclass) method, and instead calls itself again (!). To prevent this I go
class XTreeModel( DefaultTreeModel ):
def fireTreeNodesInserted( self, source, path, child_indices, children ):
print "fire nodes inserted"
self.super__fireTreeNodesInserted( source, path, child_indices, children )
... and I have learnt since starting to use Jython that these Java-base-class-calling "super__XXX" methods are in fact created spontaneously by the Jython interpreter, and only if you override a Java method in a Jython class which subclasses a Java class (as above). This is OK as far as it goes... but what if you don't know whether your superclass (baseclass) is or is not a Java class? I eventually developed the following utility method:
def get_super_method( caller, code_class ):
stack_1 = inspect.stack()[ 1 ]
func_name = stack_1[ 3 ]
# unfortunately this will return code_class.func_name as standard if code_class is a derived from a Java class with method func_name
supposed_baseclass_method = getattr( super( code_class, caller ), func_name )
for baseclass in caller.__class__.__base__.__mro__:
if "org.python.proxies" in str( baseclass ):
# ... this means we have reached down as low as a Java "proxy" class without yet encountering a class with a method 'func_name',
# which means that we must return the super__XXX version
break
# confusingly, even if you go caller.__class__.__base__.__mro__ this still shows all the classes for caller, including its highest class!
if baseclass == code_class:
continue
if func_name in baseclass.__dict__:
# ... a method with the right name exists in a baseclass...
return supposed_baseclass_method
java_baseclass_method = getattr( caller, "super__%s" % func_name )
return java_baseclass_method
which you call by going, for example:
class XTreeModel( DefaultTreeModel ):
def fireTreeNodesInserted( self, source, path, child_indices, children ):
print "X fire nodes inserted"
get_super_method( self, XTreeModel )(source, path, child_indices, children )
class XXTreeModel( XTreeModel ):
def fireTreeNodesInserted( self, source, path, child_indices, children ):
print "XX fire nodes inserted"
get_super_method( self, XXTreeModel )(source, path, child_indices, children )
Here get_super_method in XXTreeModel returns super( XXTreeModel, self )... whereas get_super_method in XTreeModel returns self.super__fireTreeNodesInserted so... maybe you could just look at the code_class passed to get_super_method and if it has "org.python.proxies" in the name of its immediate baseclass that means you return the super__XXX version, right? Er, no, it's a bit more complicated:
class XTreeModel( DefaultTreeModel ):
def do_some_stuff( self ):
print "do stuff"
class XXTreeModel( XTreeModel ):
def fireTreeNodesInserted( self, source, path, child_indices, children ):
print "XX fire nodes inserted"
get_super_method( self, XXTreeModel )(source, path, child_indices, children )
In this example, the XXTreeModel has a Jython class as its baseclass but this baseclass (XTreeModel) doesn't override the method of interest... so in fact get_super_method() in XXTreeModel needs to return super__ fireTreeNodesInserted... ... so this utility method seems to solve the problem: you don't need to know what type of class your baseclass is, whether or not it overrides the Java method, etc. Anyway, I wanted to find out whether this tortuous procedure was necessary, but googling "jython super" etc. produced bug entries from 10 years ago saying things like "use of super__ methods is deprecated".
Is there a better way to accomplish this calling of the superclass methods where your first baseclass (as you move down through the classes) with the method sought is in fact a Java class???