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
Status: closed Resolution: duplicate
Dependencies: Superseder:
Assigned To: zyasoft 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 2015-01-18.04:54:32 by zyasoft.

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

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

class PyClass1(ITest, Implementor):

class PyClass2(Implementor, ITest):

caller = Caller()

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
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):

class PyRunFirst(PyRun, Runnable):


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.
msg9354 (view) Author: Jim Baker (zyasoft) Date: 2015-01-08.04:16:38
Duplicate of #1561
Date User Action Args
2015-01-18 04:54:32zyasoftsetstatus: pending -> closed
2015-01-08 04:16:38zyasoftsetstatus: open -> pending
assignee: fwierzbicki -> zyasoft
resolution: duplicate
messages: + msg9354
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