Issue1432

classification
Title: Implementing a Java interface in a mix-in may caus calls to be ignored
Type: behaviour Severity: major
Components: Core Versions: Jython 2.7
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: fwierzbicki Nosy List: akong, alex.gronholm, cgroves, fwierzbicki, pjenvey, zyasoft
Priority: normal Keywords: patch

Created on 2009-08-12.07:26:01 by alex.gronholm, last changed 2013-02-19.19:08:30 by fwierzbicki.

Files
File name Uploaded Description Edit Remove
issue1432_hide_proxy_methods.diff cgroves, 2009-08-16.09:46:00
Messages
msg5021 (view) Author: Alex Grönholm (alex.gronholm) Date: 2009-08-12.07:26:01
ITest.java:
-----------
public interface ITest {
    void testFunc();
}

Caller.java:
------------
public class Caller {
    public void testCall(ITest testObj) {
        testObj.testFunc();
    }
}

test.py:
--------
import ITest, Caller

class Implementor():
    def testFunc(self):
        print "works"

class PyClass1(ITest, Implementor):
    pass

class PyClass2(Implementor, ITest):
    pass

caller = Caller()
caller.testCall(PyClass1())
caller.testCall(PyClass2())


One would expect the same behavior from both classes, but only the
second call actually gets through and prints "works". The first call is
happily ignored -- no warnings, no errors, no nothing! I think the
interface's method declaration is somehow overwriting the one from
Implementor.
msg5040 (view) Author: Charlie Groves (cgroves) Date: 2009-08-16.09:45:59
I opened issue 1437 to discuss PyProxy's misguided, silent creation of empty methods for abstract Java methods that don't have 
a Python method.  I'm only going to try to address the proxy's no-op method being preferred to a Python implementation here.  
You don't even need Java code to produce this:

from java.lang import Runnable

class PyRun(object):
    def run(self):
        print 'Running from', type(self)

class RunnableFirst(Runnable, PyRun):
    pass

class PyRunFirst(PyRun, Runnable):
    pass

RunnableFirst().run()
PyRunFirst().run()

prints Running from <class '__main__.PyRunFirst'> which is notably lacking input from RunnableFirst.

Your analysis that the proxy's method is being found first is correct.  Java types use Python's mro, and since the proxy class 
is the first base, its method is called first.  A simple fix for that is to exclude methods on generated proxy classes from its 
dict.  That makes them invisible from Python while leaving them in place for any calling Java code.  Unfortunately, since the 
proxy has the java interface as its base class, Jython then finds the method on the interface and attempts to call that.  We 
can prevent that by not returning abstract methods from lookups on Java classes.  The attached patch does all of that, and gets 
the code to work as expected.

It requires some pretty big changes, including some extra code in lookup, probably the most heavily used codepath in Jython.  
As such, I don't think this should go in this close to 2.5.1.  After 2.5.1 is released and stable, I'll look at actually 
committing this if I still feel good about it.
msg5663 (view) Author: Philip Jenvey (pjenvey) Date: 2010-04-11.18:17:57
#1561 is somewhat the same issue
msg5747 (view) Author: Jim Baker (zyasoft) Date: 2010-04-26.01:39:11
Probably should be addressed in 2.5.2
msg7373 (view) Author: Frank Wierzbicki (fwierzbicki) Date: 2012-08-10.20:23:35
It's definitely too late for any 2.5.x - maybe a 2.7 can use this.
History
Date User Action Args
2013-02-19 19:08:30fwierzbickisetversions: + Jython 2.7, - 2.5.0
2013-02-06 19:11:25fwierzbickisetpriority: normal
assignee: fwierzbicki
2012-08-10 20:23:35fwierzbickisetassignee: fwierzbicki -> (no value)
messages: + msg7373
2012-07-02 01:09:45fwierzbickisetassignee: fwierzbicki
nosy: + fwierzbicki
2010-06-16 21:06:42akongsetnosy: + akong
2010-04-26 01:39:11zyasoftsetnosy: + zyasoft
messages: + msg5747
2010-04-11 18:17:57pjenveysetnosy: + pjenvey
messages: + msg5663
2009-08-16 09:46:02cgrovessetfiles: + issue1432_hide_proxy_methods.diff
keywords: + patch
messages: + msg5040
2009-08-12 07:26:01alex.gronholmcreate