Issue1297

classification
Title: Methods inherited from a Java class are not overridden properly
Type: behaviour Severity: normal
Components: Core Versions: 2.5b1
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: cgroves Nosy List: alex.gronholm, cgroves, fwierzbicki, pjenvey, zyasoft
Priority: high Keywords: patch

Created on 2009-03-31.18:24:07 by alex.gronholm, last changed 2009-04-27.00:53:48 by cgroves.

Files
File name Uploaded Description Edit Remove
proxy-base-1297.diff pjenvey, 2009-04-24.02:10:35
Messages
msg4405 (view) Author: Alex Grönholm (alex.gronholm) Date: 2009-03-31.18:24:05
// Java code
package testxx;

public class JavaClass {
		
	public String test1() {
		return "JavaClass1";
	}

	public String test2() {
		return "JavaClass2";
	}

	public void printTests() {
		System.out.println(test1());
		System.out.println(test2());
	}
}

# Python code
from testxx import JavaClass

class PythonClassA(JavaClass):
    def test1(self):
        pass

class PythonClassB(PythonClassA):
    def test1(self):
        return "PythonClassB"
    def test2(self):
        return "PythonClassB"

PythonClassB().printTests()

-----------------------------
Expected result:
PythonClassB
PythonClassB

Instead I get:
PythonClassB
JavaClass2
msg4427 (view) Author: Jim Baker (zyasoft) Date: 2009-04-04.02:34:18
Substituting an equivalent python class in, new or old style, we get the
desired semantics, so that certainly violates substitutability.
msg4574 (view) Author: Philip Jenvey (pjenvey) Date: 2009-04-23.02:01:53
Indeed a regression from 2.2 (and incredibly likely pre newstyle-java-
types)
msg4583 (view) Author: Philip Jenvey (pjenvey) Date: 2009-04-24.02:10:35
The problem here is PythonClassB ends up with PythonClassA's javaProxy, 
see its toString:

Jython 2.5b3+ (trunk:6258, Apr 23 2009, 18:06:50) 
[Java HotSpot(TM) 64-Bit Server VM (Apple Inc.)] on java1.6.0_07
Type "help", "copyright", "credits" or "license" for more information.
>>> from Issue1297_ import *
>>> PythonClassA()
org.python.proxies.Issue1297_$PythonClassA$1@bf2c60d
>>> PythonClassB() # should be a $PythonClassB$1 class
org.python.proxies.Issue1297_$PythonClassA$1@48caff01

This happens because PyType doesn't add PythonClassB's proxy type to its 
__bases__ (so it's not in its mro) -- I guess PyType.setupProxy is being 
too clever

>>> PythonClassA.mro()
[<class 'Issue1297_.PythonClassA'>, <type 
'org.python.proxies.Issue1297_$PythonClassA$1'>, <type 'JavaClass'>, 
<type 'java.lang.Object'>, <type 'object'>]
>>> PythonClassA.__bases__
(<type 'org.python.proxies.Issue1297_$PythonClassA$1'>,)
>>> PythonClassB.mro()
[<class 'Issue1297_.PythonClassB'>, <class 'Issue1297_.PythonClassA'>, 
<type 'org.python.proxies.Issue1297_$PythonClassA$1'>, <type 
'JavaClass'>, <type 'java.lang.Object'>, <type 'object'>]
>>> PythonClassB.__bases__
(<class 'Issue1297_.PythonClassA'>,)

So B inherits A's javaProxy's __init__, which is a 
PyReflectedConstructor wired to create A's proxy. This problem actually 
goes away when B defines an __init__ method that'd override it

I'm not exactly sure how to best layout bases/mro intertwined with the 
proxys to fix this. Attached is a patch that fixes the problem by always 
adding the javaProxy type to bases. But this breaks a couple 
test_java_subclasses tests. Charlie, can you take a look at this for the 
2.5rc?
msg4598 (view) Author: Charlie Groves (cgroves) Date: 2009-04-27.00:53:47
Should be fixed in r6263.
History
Date User Action Args
2009-04-27 00:53:48cgrovessetstatus: open -> closed
resolution: accepted -> fixed
messages: + msg4598
2009-04-24 02:10:37pjenveysetfiles: + proxy-base-1297.diff
assignee: pjenvey -> cgroves
messages: + msg4583
keywords: + patch
2009-04-24 00:10:25pjenveysetassignee: pjenvey
2009-04-23 02:01:54pjenveysetnosy: + pjenvey
messages: + msg4574
2009-04-04 02:34:18zyasoftsetpriority: high
nosy: + cgroves, fwierzbicki, zyasoft
resolution: accepted
messages: + msg4427
2009-03-31 18:24:07alex.gronholmcreate