Issue1002

classification
Title: static java methods on class hidden by object methods
Type: Severity: normal
Components: Core Versions: Jython 2.7, Jython 2.5, Jython 2.2
process
Status: open Resolution: remind
Dependencies: Superseder:
Assigned To: fwierzbicki Nosy List: akong, crotwell, fwierzbicki, pzack
Priority: low Keywords: patch

Created on 2008-02-29.20:12:24 by crotwell, last changed 2013-02-19.18:32:18 by fwierzbicki.

Files
File name Uploaded Description Edit Remove
PyReflectedFunction.java pzack, 2008-03-16.17:01:37 PyReflectedFunction that will resolve static methods correctly
object_static_method.diff crotwell, 2008-12-17.21:05:15
Messages
msg3057 (view) Author: Philip Crotwell (crotwell) Date: 2008-02-29.20:12:23
If there is a method of the same name as both static and on the object,
the static one can't be called. For example Class.getName() works on URL
because there is no getName() object method, but toString() does not
because there is both a object toString() in URL and a toString() on the
Class object:

crotwell$ java -jar output/lib/jython-2.2.1.jar 
Jython 2.2.1 on java1.5.0_13
Type "copyright", "credits" or "license" for more information.
>>> from java.net import URL 
>>> URL.getName()
'java.net.URL'
>>> URL.toString()
Traceback (innermost last):
  File "<console>", line 1, in ?
TypeError: toString(): expected 1 args; got 0
>>> 

Interestingly, the str() function seems to find the toString on the class:

>>> str(URL)
'java.net.URL'
msg3080 (view) Author: Anthony Kong (akong) Date: 2008-03-10.14:03:01
URL.toString() itself is not a valid Java code.

For example:

=====

package test;

import java.net.URL;

class M {

  public M(){
  }

  public static void main(String [] argv) {
    System.out.println(URL.toString());
  }
}
=====
javac will say:

test/M.java:12: non-static method toString() cannot be referenced from a
static context
    System.out.println(URL.toString());
msg3081 (view) Author: Philip Crotwell (crotwell) Date: 2008-03-10.14:37:22
But URL.toString() is valid jython. The equivalent in java would be
URL.class.toString() which generates:
class java.net.URL
msg3088 (view) Author: Zack Thunemann (pzack) Date: 2008-03-16.17:01:36
This *is* a bug.  Consider this java code:

package test;


public class MyClass {
   

   public static String func(MyClass c)
   {
      return "In static function";
   }
   
   public String func()
   {
      return "In class method";
   }
}



and this jython code:


from test import MyClass

mc = MyClass()
print mc.func()
print MyClass.func(mc)
print 'Test complete'


The Output is:
In class method
In class method
Test complete

this is wrong.

I've attached a modification to the __call__ method in 
org.python.core.PyRefectedFunction that will repair this
method resolution order.  I'll create a patch for this later.

-Zack
msg3089 (view) Author: Zack Thunemann (pzack) Date: 2008-03-16.17:18:35
Also, there is no static 'toString' method in java.net.URL,
so I don't think the behavior that the OP expected is correct.
msg3946 (view) Author: Frank Wierzbicki (fwierzbicki) Date: 2008-12-17.14:54:14
I don't agree that we should expose java.net.URL the way that is
suggested here.  If I was able to reproduce the behavior in msg3088 (the
MyClass example) that would be a bug, but my local install of Jython
2.2.1, the maint 2.2 branch, and 2.5 produce this for me:

In instance method
In static func
Test complete

So I am closing this bug.
msg3947 (view) Author: Frank Wierzbicki (fwierzbicki) Date: 2008-12-17.14:56:16
BTW I changed the MyClass output as I typed it in -- for reference I used:

ackage test;

public class MyClass {

    public static String func(MyClass c) {
        return "In static func";
    }

    public static String func() {
        return "In instance method";
    }

}

called with:

from test import MyClass

mc = MyClass()
print mc.func()
print MyClass.func(mc)
print 'Test complete'
msg3951 (view) Author: Philip Crotwell (crotwell) Date: 2008-12-17.16:02:17
Can you explain why you changed the test case to be both static methods?
The original posting was an __object__ method hiding a static method. So
two static methods is really a completely different case, one which has
worked fine all along and is not relevant to this bug.

In Java I can do this:
   System.out.println(URL.class.toString());
which prints 
java.net.URL

How would you call the equivalent in jython? 

If you try URL.toString() you get an error. You can't create a URL
instance and then call toString() because then you will get the toString
on the URL instance instead of the class.

Perhaps there is not a good way with python syntax to fix this in
jython, but I would humbly suggest that his bug should not be closed
based on your two static method test.
msg3952 (view) Author: Frank Wierzbicki (fwierzbicki) Date: 2008-12-17.18:19:16
oops, that explains why I couldn't reproduce it... :(

Re-opening and re-examining.
msg3953 (view) Author: Frank Wierzbicki (fwierzbicki) Date: 2008-12-17.18:33:31
Philip Crotwell: could you submit the patch as a diff as in
http://www.jython.org/Project/devfaq.html#patches?
msg3958 (view) Author: Philip Crotwell (crotwell) Date: 2008-12-17.21:05:15
Attached is the patch. However, it didn't come from me, but from Zack
Thunemann. I think I have copied his code into
PyReflectedFunction.__call__ in the latest svn and created a patch from
that, attached. It seems to address the issue shown with his MyClass
java code.

However, this patch does not address the original issue. Here is output
from jython with the patch and the class from message 3088. The test of
MyClass now works correctly. However, the original example of
java.net.URL.toString() still fails. Perhaps there is more to it in this
case as toString() is not truely a static method at all, but really an
object method on the object java.lang.Class. I am not sure of how to
modify __call__ to detect this case. 


rabbit:~/dev/jython/jython/dist crotwell$ bin/jython
Jython 2.5b0+ (trunk:5774M, Dec 17 2008, 15:46:30) 
[Java HotSpot(TM) Client VM ("Apple Computer, Inc.")] on java1.5.0_16
Type "help", "copyright", "credits" or "license" for more information.
>>> from test import MyClass

mc = MyClass()
print mc.func()
print MyClass.func(mc)
print 'Test complete'
>>> >>> >>> In class method
>>> In static function
>>> Test complete
>>> 
>>> 
>>> from java.net import URL
>>> URL.toString()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: toString(): expected 1 args; got 0
msg3966 (view) Author: Frank Wierzbicki (fwierzbicki) Date: 2008-12-18.22:38:43
Hey Philip, thanks for making that a diff even though it wasn't your
patch!  BTW it looks like the basic issue is quite old (and must be
difficult since Samuele Pedroni, a former lead of Jython who really
knows his stuff, seems to shrug in this bug report that looks to me like
the same issue: http://bugs.jython.org/issue508116)
History
Date User Action Args
2013-02-19 18:32:18fwierzbickisetversions: + Jython 2.5, Jython 2.7
2013-02-19 18:31:58fwierzbickisetresolution: remind
versions: + Jython 2.2, - 2.2.2
2012-08-10 20:00:02fwierzbickisetassignee: fwierzbicki
2009-03-14 14:21:07fwierzbickisetpriority: low
2008-12-18 22:38:44fwierzbickisetmessages: + msg3966
2008-12-17 21:05:17crotwellsetfiles: + object_static_method.diff
keywords: + patch
messages: + msg3958
2008-12-17 18:33:31fwierzbickisetresolution: invalid -> (no value)
messages: + msg3953
2008-12-17 18:19:17fwierzbickisetstatus: closed -> open
messages: + msg3952
2008-12-17 16:02:18crotwellsetmessages: + msg3951
2008-12-17 14:56:16fwierzbickisetmessages: + msg3947
2008-12-17 14:54:15fwierzbickisetstatus: open -> closed
resolution: invalid
messages: + msg3946
2008-03-16 17:18:35pzacksetmessages: + msg3089
2008-03-16 17:01:37pzacksetfiles: + PyReflectedFunction.java
nosy: + pzack
messages: + msg3088
2008-03-10 14:37:22crotwellsetmessages: + msg3081
2008-03-10 14:03:01akongsetnosy: + akong
messages: + msg3080
2008-03-07 16:47:40fwierzbickisetnosy: + fwierzbicki
2008-02-29 20:12:24crotwellcreate