Issue2634

classification
Title: Cannot access final protected methods
Type: behaviour Severity: normal
Components: Core Versions: Jython 2.7
Milestone:
process
Status: open Resolution: accepted
Dependencies: Superseder:
Assigned To: jeff.allen Nosy List: alexgobbo, jeff.allen, jon4than
Priority: normal Keywords:

Created on 2017-10-23.09:39:52 by alexgobbo, last changed 2018-03-10.07:51:12 by jeff.allen.

Messages
msg11630 (view) Author: A. Gobbo (alexgobbo) Date: 2017-10-23.09:39:50
Jython cannot access final protected methods. For example the code:


package test;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

public class Final {
    public static class TestClass {
        protected void method1() {
            System.out.println("On protected");
        }
        final public void method2() {
            System.out.println("On final public");
        }        
        final protected void method3() {
            System.out.println("On final protected");
        }        
    }

    public static void main(String[] args) throws Exception {
        ScriptEngine engine = new ScriptEngineManager().getEngineByName("python");

        engine.eval("import test.Final.TestClass");
        
        engine.eval("class MyClass(test.Final.TestClass):\n"
                + "   def m1(self):\n"
                + "       self.method1()\n"
                + "   def m2(self):\n"
                + "       self.method2()\n"
                + "   def m3(self):\n"
                + "       self.method3()\n");
        engine.eval("o = MyClass()");        
        
        engine.eval("o.m1()");
        engine.eval("o.m2()");
        engine.eval("o.m3()");
    }
}


Outputs:

On protected
On final public
Exception in thread "main" javax.script.ScriptException: AttributeError: 'MyClass' object has no attribute 'method3' in <script> at line number 1
	at org.python.jsr223.PyScriptEngine.scriptException(PyScriptEngine.java:202)
	at org.python.jsr223.PyScriptEngine.eval(PyScriptEngine.java:42)
	at org.python.jsr223.PyScriptEngine.eval(PyScriptEngine.java:31)
	at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264)
	at test.Final.main(Final.java:44)
Caused by: Traceback (most recent call last):
  File "<script>", line 1, in <module>
  File "<script>", line 7, in m3
AttributeError: 'MyClass' object has no attribute 'method3'

	at org.python.core.Py.AttributeError(Py.java:205)
	at org.python.core.PyObject.noAttributeError(PyObject.java:1013)
	at org.python.core.PyObject.__getattr__(PyObject.java:1008)
	at org.python.pycode._pyx1.m3$4(<script>:7)
	at org.python.pycode._pyx1.call_function(<script>)
	at org.python.core.PyTableCode.call(PyTableCode.java:167)
	at org.python.core.PyBaseCode.call(PyBaseCode.java:138)
	at org.python.core.PyFunction.__call__(PyFunction.java:413)
	at org.python.core.PyMethod.__call__(PyMethod.java:126)
	at org.python.pycode._pyx5.f$0(<script>:1)
	at org.python.pycode._pyx5.call_function(<script>)
	at org.python.core.PyTableCode.call(PyTableCode.java:167)
	at org.python.core.PyCode.call(PyCode.java:18)
	at org.python.core.Py.runCode(Py.java:1386)
	at org.python.core.__builtin__.eval(__builtin__.java:497)
	at org.python.core.__builtin__.eval(__builtin__.java:501)
	at org.python.util.PythonInterpreter.eval(PythonInterpreter.java:259)
	at org.python.jsr223.PyScriptEngine.eval(PyScriptEngine.java:40)
	... 3 more
msg11658 (view) Author: Jonathan Beavers (jon4than) Date: 2017-11-17.20:46:02
Apologies if this isn't the correct place to put this sort of reply, but did you try setting python.security.respectJavaAccessibility to false?

Running the following reproduced your problem:
  java -cp .:jython-standalone-2.7.0.jar test.Final

I was able to fix it by running:
  java -cp .:jython-standalone-2.7.0.jar -Dpython.security.respectJavaAccessibility=false test.Final
msg11664 (view) Author: A. Gobbo (alexgobbo) Date: 2017-11-20.07:39:53
I believe it is not a solution. Setting respectJavaAccessibility to false makes all members accessible, including the private ones, and that's not what I'd expect if extending a Java class.
msg11773 (view) Author: Jeff Allen (jeff.allen) Date: 2018-03-10.07:51:11
At first I wondered whether (since MyClass is not a Java subclass of TestClass) this should be allowed, but protected method1 is accessible when protected final method3 is not, which is silly. I'm assuming both should be accessible.

After an initial investigation, I believe we should blame the construction of the MRO for MyClass, in  PyType.newType .. PyType.setupProxy .. MakeProxies.makeProxy. "method3" seems simply not to get into the list, although various related names do, as seen from PyType.lookup_where_mro.

I'm assigning to me provisionally as I've tunnelled in quite a way just to understand it.
History
Date User Action Args
2018-03-10 07:51:12jeff.allensetpriority: normal
assignee: jeff.allen
resolution: accepted
messages: + msg11773
nosy: + jeff.allen
2017-11-20 07:39:54alexgobbosetmessages: + msg11664
2017-11-17 20:46:03jon4thansetnosy: + jon4than
messages: + msg11658
2017-10-23 09:39:52alexgobbocreate