Issue1587

classification
Title: Incorrect method resolution order (MRO) error when implementing java interfaces
Type: behaviour Severity: major
Components: Core Versions: 2.5.1
process
Status: closed Resolution: duplicate
Dependencies: Superseder:
Assigned To: Nosy List: matt_brinkley, pjenvey
Priority: Keywords:

Created on 2010-03-29.20:14:08 by matt_brinkley, last changed 2010-04-11.02:04:44 by pjenvey.

Messages
msg5608 (view) Author: Matt Brinkley (matt_brinkley) Date: 2010-03-29.20:14:06
If you create a hierarchy of Python classes that implement Java interfaces as shown below, jython will (incorrectly) emit the error:     

class SpaceDog(HoundDog):
TypeError: Error when calling the metaclass bases
    Cannot create a consistent method resolution
order (MRO) for bases HoundDog[<class 'jytest.Dog'>, <type 'org.python.proxies.jytest$HoundDog$1'>]


Here is the test file which causes the error:

--------------------------------------------------------------
from java.lang import Runnable, Comparable

class Dog(Runnable):
    def run(self):
        print "I ran"

class HoundDog(Dog, Comparable):
    def compareTo(self, o):
        return 0

class SpaceDog(HoundDog):
    pass
    
--------------------------------------------------------------


I spent some time walking through the debugger, and there seems to be something incorrect with the method PyType.computeMro() .. in particular, the following code snippet isn't working right; it adds the proxy object to the MRO list for HoundDog even though it is already in the list; having two classes in the MRO list for HoundDog is what causes SpaceDog to blow up with the MRO error.

           if (!addedProxy && !(this instanceof PyJavaType) && candidate instanceof PyJavaType
                    && candidate.javaProxy != null
                    && PyProxy.class.isAssignableFrom(((Class<?>)candidate.javaProxy))
                    && candidate.javaProxy != javaProxy) {
                // If this is a subclass of a Python class that subclasses a Java class, slip the
                // proxy for this class in before the proxy class in the superclass' mro.
                // This exposes the methods from the proxy generated for this class in addition to
                // those generated for the superclass while allowing methods from the superclass to
                // remain visible from the proxies.
                addedProxy = true;
                mro.add(PyType.fromClass(((Class<?>)javaProxy)));
            }
msg5656 (view) Author: Philip Jenvey (pjenvey) Date: 2010-04-11.02:04:44
This must be a duplicate of #1504, which is already fixed on trunk. Your test script works fine on there
History
Date User Action Args
2010-04-11 02:04:44pjenveysetstatus: open -> closed
resolution: duplicate
messages: + msg5656
nosy: + pjenvey
2010-03-29 20:14:08matt_brinkleycreate