From: Oti <oh...@ya...> - 2002-10-30 21:22:05
|
Hello Finn, while you are in the mood of deciding over patches :-), I hope you don't mind if I ask this one. I got a positive response (along with a suggestion for a better implementation) from Ype Kingma: > Couldn't you override ifindfunction in PyJavaInstance.java ? > That might also simplify the logic needed > as __class__.getProxyClass() would allways be true, > (and would __class__.__getattr__ not always be null?) > and cause a bit less overhead for non PyJavaInstance's. > It would also limit the changes to one source file. and also a positive response from Jim Adrig: http://aspn.activestate.com/ASPN/Mail/Message/Jython-dev/1270870 What do you think of the idea below? Is it worth opening a patch ? If yes, I would try to create a proper cvs diff against HEAD. Many thanks for your feedback! Oti. Here it goes: Motivation: ----------- if a java class X implements methods __add__() __sub__(), ... these methods are invoked if i use x = X() x + 10 x - 10 in the interpreter. Similarly, if X implements methods __eq__(), __lt__(), ... these methods are invoked if i use x = X() x == 10 x < 10 in the interpreter. This is cool, pretty cool i'd say. In both cases it is the java class' responsibility to do and/or return something useful. Idea / Question: ---------------- Now it would be even cooler if methods __getattr__() __setattr__() would be invoked if i use x = X() x.undefinedAttribute x.undefinedAttribute = 10 x.undefinedMethod() Again it would be the java class' responsibility to do and/or return something useful. It can be done: --------------- The changes below (the change suggested by Ype, respectively) against the 2.1 codebase enable the above. 1) File /core/PyJavaInstance.java: Old method: protected void noField(String name, PyObject value) { throw Py.TypeError("can't set arbitrary attribute in java instance: " + name); } replaced with: protected void noField(String name, PyObject value) { PyObject method = __class__.lookup("__setattr__", false); if ( method == null ) { throw Py.TypeError("can't set arbitrary attribute in java instance: " + name); } else { method.__call__(this, new PyString(name), value); } } 2) File /core/PyInstance.java: Old method: protected PyObject ifindfunction(String name) { PyObject getter = __class__.__getattr__; if (getter == null) return null; try { return getter.__call__(this, new PyString(name)); } catch (PyException exc) { if (Py.matchException(exc, Py.AttributeError)) return null; throw exc; } } replaced with: protected PyObject ifindfunction(String name) { PyObject getter = __class__.__getattr__; if ( getter == null && __class__.getProxyClass() != null ) { getter = __class__.lookup("__getattr__", false); } if ( getter == null ) { return null; } try { return getter.__call__(this, new PyString(name)); } catch (PyException exc) { if (Py.matchException(exc, Py.AttributeError)) return null; throw exc; } } __________________________________________________ Do you Yahoo!? HotJobs - Search new jobs daily now http://hotjobs.yahoo.com/ |
From: Finn B. <bc...@wo...> - 2002-11-01 15:05:35
|
[Oti] > Hello Finn, > > while you are in the mood of deciding over patches :-), I hope you > don't mind if I ask this one. > > I got a positive response (along with a suggestion for a better > implementation) from Ype Kingma: > > Couldn't you override ifindfunction in PyJavaInstance.java ? > > That might also simplify the logic needed > > as __class__.getProxyClass() would allways be true, > > (and would __class__.__getattr__ not always be null?) > > and cause a bit less overhead for non PyJavaInstance's. > > It would also limit the changes to one source file. Well, I don't like this feature that much. It just seems too magicly for my taste (and yes, I also find the calls to __getitem__ etc. too magicly). Since this is java, I think the methods should be more staticly bound. Or at the very least, that a java class should announce that it want to participate in the jython operator game. F.ex by extending an interface. regards, finn |
From: Samuele P. <ped...@bl...> - 2002-11-01 15:22:01
|
From: "Finn Bock" <bc...@wo...> > [Oti] > > > Hello Finn, > > > > while you are in the mood of deciding over patches :-), I hope you > > don't mind if I ask this one. > > > > I got a positive response (along with a suggestion for a better > > implementation) from Ype Kingma: > > > Couldn't you override ifindfunction in PyJavaInstance.java ? > > > That might also simplify the logic needed > > > as __class__.getProxyClass() would allways be true, > > > (and would __class__.__getattr__ not always be null?) > > > and cause a bit less overhead for non PyJavaInstance's. > > > It would also limit the changes to one source file. > > Well, I don't like this feature that much. It just seems too magicly for > my taste (and yes, I also find the calls to __getitem__ etc. too > magicly). Since this is java, I think the methods should be more > staticly bound. > Or at the very least, that a java class should announce > that it want to participate in the jython operator game. F.ex by > extending an interface. I agree, OTOH the fact that __add__ etc work is a pure side-effect of the current implementation, just a side-effect, I don't know if intentional but kind of natural. If things stay as they are, we would have to_do_ something to block this. It's one of the corner cases that should be considered for the java intergration review that should go in parallel with how to implement new-style classes. regards. |
From: Ype K. <yk...@xs...> - 2002-11-04 20:58:22
|
Oti, Samuele, Finn, Some random thoughts. On Friday 01 November 2002 16:12, Samuele Pedroni wrote: > From: "Finn Bock" <bc...@wo...> > > > [Oti] > > > > > Hello Finn, > > > > > > while you are in the mood of deciding over patches :-), I hope you > > > don't mind if I ask this one. > > > > > > I got a positive response (along with a suggestion for a better > > > > > > implementation) from Ype Kingma: > > > > Couldn't you override ifindfunction in PyJavaInstance.java ? > > > > That might also simplify the logic needed > > > > as __class__.getProxyClass() would allways be true, > > > > (and would __class__.__getattr__ not always be null?) > > > > and cause a bit less overhead for non PyJavaInstance's. > > > > It would also limit the changes to one source file. > > > > Well, I don't like this feature that much. It just seems too magicly = for > > my taste (and yes, I also find the calls to __getitem__ etc. too > > magicly). Since this is java, I think the methods should be more > > staticly bound. > > > > Or at the very least, that a java class should announce > > that it want to participate in the jython operator game. F.ex by > > extending an interface. Such an interface could be called eg. EmulatePyObject, after chapter 3.3 of the language reference. 'Special method names' which contains ao: "When implementing a class that emulates any built-in type, it is importa= nt=20 that the emulation only be implemented to the degree that it makes sense = for=20 the object being modelled." This concerns implementations in python, but it might equally apply to=20 implementations in java. This special interface should be empty and serve as a flag that special methods are to be delegated to the underlying java object, much like=20 Serializable. Is it possible to implement such methods in a Java object without incurri= ng=20 the runtime cost of testing whether some special interface is implemented= ? It seems to me that one way to do that is at wrapping time of the java=20 object: when it implements this EmulatePyObject interface it would be wra= pped=20 with a class somewhat similar to PyJavaInstance, eg. PyEmulatingJavaInsta= nce, that would then provide for more 'magical' behaviour, eg. as suggested above by Oti. > I agree, OTOH the fact that __add__ etc work is a pure side-effect of t= he > current implementation, just a side-effect, I don't know if intentional= but > kind of natural. If things stay as they are, we would have to_do_ somet= hing > to block this. Not necessarily: it is also possible to have the point of view that it is= =20 currently no problem to call most java methods by explicitly calling them= =20 from python. To emulate a python object in java it is therefore only=20 necessary to emulate it in python code and to call other java methods fro= m=20 such python code, eg. using inheritance or delegation. The current side-effect is just a side effect: it might only be guarantee= d=20 that it will never be guaranteed behaviour. One valid reason to allow python object emulation directly in java would = be that the python part with the special methods is too slow. But I don't think that is currently the case: when jython gets too slow, = one=20 can always revert to java anyway. > It's one of the corner cases that should be considered for the java > intergration review that should go in parallel with how to implement > new-style classes. Some time ago I have also suggested to make PyObject implement java's=20 Comparable in order to allow easier use of python objects in java=20 collections. This is a mapping back from java to python, ie java compareT= o()=20 to python __cmp__(). (This was before 2.1 introduced __lt__() and friends= =2E) A similar mapping from toString() to __str__ is also possible, but that=20 introduces the problem of possible infinite recursion. The sugar that Jython currently provides is oa. - the java bean properties, - __str__ implemented by java's toString(). - __del__() implemented by java's finalize(), - some java maps behaving surprisingly similar to python dictionaries - java enumerations/iterators usable in python for statements. - indexing of and iteration over java arrays. Some more examples that are not available and/or not documented: Java Python hash() __hash__() equals() __eq__() size() __len__() =20 iterator() __iter__()=20 containsValue() __contains__() isEmpty() not __nonzero__() keySet() keys() All of these are more or less 'cool' or 'natural'. The question is: what=20 criteria will be applied for inclusion of more such mappings in jython? Eg: (1) not allowed when possible in python code, or (2) only allowed when only possible in the java code of jython's=20 implementation, but (3) allow a mapping when java has a really close counterpart to a python=20 feature, or (4) anything goes, as long as it is conform the python language reference= , is=20 easily understood by java programmers using jython, and does not hurt=20 performance. Although there some current features contradict (1), I wouldn't mind (2) = and=20 (3) for new features. That means that I'm not in faviour of an EmulatePyObject interface for ja= va=20 objects because it can be done in python. Sorry Oti. Regards, Ype |
From: Finn B. <bc...@wo...> - 2002-11-06 08:47:41
|
[Ype Kingma] > Oti, Samuele, Finn, > > Some random thoughts. [me] >> Or at the very least, that a java class should announce >> that it want to participate in the jython operator game. F.ex by >> extending an interface. [Ype] > Such an interface could be called eg. EmulatePyObject, > after chapter 3.3 of the language reference. 'Special method names' > which contains ao: > "When implementing a class that emulates any built-in type, it is important > that the emulation only be implemented to the degree that it makes sense for > the object being modelled." > This concerns implementations in python, but it might equally apply to > implementations in java. > This special interface should be empty and serve as a flag that special > methods are to be delegated to the underlying java object, much like > Serializable. That is exactly what I had in mind. > Is it possible to implement such methods in a Java object without incurring > the runtime cost of testing whether some special interface is implemented? > It seems to me that one way to do that is at wrapping time of the java > object: when it implements this EmulatePyObject interface it would be wrapped > with a class somewhat similar to PyJavaInstance, eg. PyEmulatingJavaInstance, > that would then provide for more 'magical' behaviour, eg. as suggested > above by Oti. [Samuele] >>I agree, OTOH the fact that __add__ etc work is a pure side-effect of the >>current implementation, just a side-effect, I don't know if intentional but >>kind of natural. If things stay as they are, we would have to_do_ something >>to block this. > Not necessarily: it is also possible to have the point of view that it is > currently no problem to call most java methods by explicitly calling them > from python. To emulate a python object in java it is therefore only > necessary to emulate it in python code and to call other java methods from > such python code, eg. using inheritance or delegation. > The current side-effect is just a side effect: it might only be guaranteed > that it will never be guaranteed behaviour. I'll have to be carefull here, but I suspect that we may be misunderstanding each other. I agree completely with Samuele, that from the POV of the implementation, the current behaviour really looks like a side-effect of PyJavaClass being a subclass of PyClass. I also that it is kind of natural and very usefull for a java class to suply an __add__ method and have it work without subclassing PyObject. I just don't want to add it to the current implementation and to guaranty that it works. > One valid reason to allow python object emulation directly in java would be > that the python part with the special methods is too slow. There are other and better reasons, but it is not the lack of good reasons that make me hesitate. > But I don't think that is currently the case: when jython gets too slow, one > can always revert to java anyway. [Samuele] >>It's one of the corner cases that should be considered for the java >>intergration review that should go in parallel with how to implement >>new-style classes. That could not be more true. regards, finn |
From: Oti <oh...@ya...> - 2002-11-06 05:37:37
|
[ Finn Bock ] > Well, I don't like this feature that much. It just seems too magicly > for > my taste (and yes, I also find the calls to __getitem__ etc. too > magicly). Since this is java, I think the methods should be more > staticly bound. Or at the very least, that a java class should > announce > that it want to participate in the jython operator game. F.ex by > extending an interface. Hello Finn, Samuele and Ype, thank you very much for the time you put into the discussion of this idea! Maybe I have to go one step back to explain, from a higher level point of view, what I want to do and why: Enable java classes to implement 'Special Methods' (Jython Essentials chapter 5, pages 98-103). from page 99: "Using special methods well enables your classes to have the look and feel of Python's built-in types, and allows you the convenience of, for example, using + instead of add() for your list-like types." I want to use them well for *java* classes. Now why (Ype wrote 'it can be done in python')? I try to show with an example what the benefits of doing it in java would be. Let Entity be a generic java class representing any database table. Instances of Entity (like Person, Address, Order etc.) have generic attribute access methods and database query methods. A very simplified implementation of Entity could look like this: public class Entity { public Entity(String tableName) {...} public Datatype getAttribute(String name) {...} public void setAttribute(String name, Object value) {...} /** returns a 'result set' */ public Entity[] query(String selectionName) {...} } public class Datatype { public Datatype( Object value ) {...} public int compareTo( Object other ) {...} public boolean equals( Object other ) {...} public Datatype add( Datatype other ) } Without special method support, scripting in Jython looks like this: user1 = Entity("Person") user1.setAttribute("name", "first user") user1.setAttribute("age", 25) user2 = Entity("Person") user2.setAttribute("name", "second user") user2.setAttribute("age", 35) # comparisons and arithmetic operations get really awkward if user1.getAttribute("age").compareTo(user2.getAttribute("age") == 0: print "%s has the same age like %s" % (user1.getAttribute("name"), user2.getAttribute("name")) user1.setAttribute("age", user1.getAttribute("age").add(1) # queries look very unnatural for p in user1.query("ByANonUniqueCriterion"): # do something with p user1.setAttribute("name", "new name") if len(user1.query("PrimaryKey")) == 1: print "%s is unique" % user1.getAttribute("name") With special method support, and Entity implementing __setattr__/__getattr__, and Datatype implementing __eq__, __iadd__ etc., the same example gets: user1 = Entity("Person") user1.name = "first user" user1.age = 25 user2 = Entity("Person)" user2.name = "second user" user2.age = 35 # comparisons and arithmetic operations get really elegant if user1.age == user2.age: print "%s has the same age like %s" % (user1.name, user2.name) user1.age += 1 # queries are natural method calls for p in user1.queryByANonUniqueCriterion(): # do something with p user1.name = "new name" if len(user1.queryPrimaryKey()) == 1: print "%s is unique" % user1.name To summarize, let's look at a list of benefits: - start scripting right away - no need for python wrapper classes - python and java classes have the same look and feel - end user friendly Can we, regardless of any actual or future implementation details and in the name of a closer java integration, all agree that 'enabling Special Methods for java classes' is a desirable feature for Jython ? If yes, let's discuss how we can get there. Best wishes, Oti. __________________________________________________ Do you Yahoo!? HotJobs - Search new jobs daily now http://hotjobs.yahoo.com/ |
From: Finn B. <bc...@wo...> - 2002-11-06 12:00:56
|
[Oti] > To summarize, let's look at a list of benefits: > - start scripting right away > - no need for python wrapper classes You realize that a wrapper instance is needed in any case, it is just created dynamicly by jython. > - python and java classes have the same look and feel > - end user friendly > Can we, regardless of any actual or future implementation details and > in the name of a closer java integration, all agree that 'enabling > Special Methods for java classes' is a desirable feature for Jython ? Yes. Neither Samuele or I said that it wasn't a natural feature. It is just that neither of us want to add the feature as a small patch to the PyJavaClass. I reached that conclusion from looking at the existing code, and I suspect that Samuele reached the same conclusion from looking at the same code. > If yes, let's discuss how we can get there. Perhaps it is better to think of the feature as a sort of light-weight PyObject. regards, finn |
From: Oti <oh...@ya...> - 2002-11-07 06:04:06
|
> [me] > > To summarize, let's look at a list of benefits: > > - start scripting right away > > - no need for python wrapper classes [ Finn ] > You realize that a wrapper instance is needed in any case, it is just > created dynamicly by jython. Yes. By 'wrapper class' above I meant a class written in python, like: [ Ype ] > To emulate a python object in java it is therefore only > necessary to emulate it in python code and to call other java methods > from such python code, eg. using inheritance or delegation. [ me ] > > Can we, regardless of any actual or future implementation details, > > in the name of a closer java integration, all agree that 'enabling > > Special Methods for java classes' is a desirable feature for Jython ? > > Yes. uff, big stone rolling off my heart... [ Finn ] > Neither Samuele or I said that it wasn't a natural feature. It is > just > that neither of us want to add the feature as a small patch to the > PyJavaClass. sorry for misunderstanding you both in the first place. > I reached that conclusion from looking at the existing code, and I > suspect that Samuele reached the same conclusion from looking at the > same code. > > > If yes, let's discuss how we can get there. > > Perhaps it is better to think of the feature as a sort of > light-weight PyObject. Ok, I see. More like: [ Ype ] > This special interface should be empty and serve as a flag that > special methods are to be delegated to the underlying java object, > much like Serializable. [ Finn ] > That is exactly what I had in mind. [ Ype ] > It seems to me that one way to do that is at wrapping time of the > java object: when it implements this EmulatePyObject interface it > would be wrapped with a class somewhat similar to PyJavaInstance, eg. > PyEmulatingJavaInstance This approach is much better than my first one. Do I get a chance to implement it a second time, without conflicting with tasks 60919/60924, or is someone else already working on it, or has planned to ? Thanks, and best wishes, Oti. __________________________________________________ Do you Yahoo!? U2 on LAUNCH - Exclusive greatest hits videos http://launch.yahoo.com/u2 |
From: Ype K. <yk...@xs...> - 2002-11-07 18:20:34
|
A few more random thoughts. On Thursday 07 November 2002 07:04, Oti wrote: <snip> > > Perhaps it is better to think of the feature as a sort of > > light-weight PyObject. > > Ok, I see. More like: > > [ Ype ] > > > This special interface should be empty and serve as a flag that > > special methods are to be delegated to the underlying java object, > > much like Serializable. > > [ Finn ] > > > That is exactly what I had in mind. > > [ Ype ] > > > It seems to me that one way to do that is at wrapping time of the > > java object: when it implements this EmulatePyObject interface it > > would be wrapped with a class somewhat similar to PyJavaInstance, eg. > > PyEmulatingJavaInstance > > This approach is much better than my first one. Do I get a chance to > implement it a second time, without conflicting with tasks 60919/60924, > or is someone else already working on it, or has planned to ? One small problem I see is that adding this interface definition to a java class gets in the way of 'starting scripting right away' from Oti's wishlist: one will have to think of adding this _before_ compiling the Java class to be scripted. OTOH, wrapping the objects to be scripted takes only a few lines of pytho= n=20 code, eg: from JythonFacilitiies import scriptableObject as s so1 =3D s(YourClassToBeScripted()) Where jythonfactilies would eg. contain class or function scriptableObject which would add all the magic needed and delegate the rest to the javaObject. I get the feeling I'm missing some of the dis- and advantages of=20 both methods (in python and in java). Regards, Ype |
From: Oti <oh...@ya...> - 2002-11-11 06:31:55
|
[ Ype Kingma ] > One small problem I see is that adding this interface definition > to a java class gets in the way of 'starting scripting right away' > from Oti's wishlist: one will have to think of adding this _before_ > compiling the Java class to be scripted. 'right away' for my case means after compilation of java sources. I need to control at compile time which java classes will be enabled for python special methods. > OTOH, wrapping the objects to be scripted takes only a few lines of > python > code, eg: > > from JythonFacilitiies import scriptableObject as s > so1 = s(YourClassToBeScripted()) > > Where jythonfactilies would eg. contain class or function > scriptableObject which would add all the magic needed > and delegate the rest to the javaObject. This is true, and in fact I have been doing it this way for a long time now. But it turned out that users were too confused about when to use this facility and when not. I try to give an example: Assume returnNumber() returns a number: result = s(javaObject.returnNumber()) + jythonObject.returnNumber() The problem here is: when do you have to wrap a value with a call to s(), and when not ? It turns out that, on every line with an arithmetic calculation, or a comparison, you have to *know* what kind of object you are treating. This fundamentally conflicts with pythons dynamic nature. > I get the feeling I'm missing some of the dis- and advantages of > both methods (in python and in java). I hope I could at least give you a feeling... Best wishes, Oti. __________________________________________________ Do you Yahoo!? U2 on LAUNCH - Exclusive greatest hits videos http://launch.yahoo.com/u2 |
From: Ype K. <yk...@xs...> - 2002-11-11 18:49:31
|
On Monday 11 November 2002 07:31, Oti wrote: > [ Ype Kingma ] > > > One small problem I see is that adding this interface definition > > to a java class gets in the way of 'starting scripting right away' > > from Oti's wishlist: one will have to think of adding this _before_ > > compiling the Java class to be scripted. > > 'right away' for my case means after compilation of java sources. > I need to control at compile time which java classes will be enabled > for python special methods. > > > OTOH, wrapping the objects to be scripted takes only a few lines of > > python > > code, eg: > > > > from JythonFacilitiies import scriptableObject as s > > so1 =3D s(YourClassToBeScripted()) > > > > Where jythonfactilies would eg. contain class or function > > scriptableObject which would add all the magic needed > > and delegate the rest to the javaObject. > > This is true, and in fact I have been doing it this way for a long time > now. But it turned out that users were too confused about when to use > this facility and when not. I try to give an example: > Assume returnNumber() returns a number: > result =3D s(javaObject.returnNumber()) + jythonObject.returnNumber() > The problem here is: when do you have to wrap a value with a call to > s(), and when not ? It turns out that, on every line with an arithmetic > calculation, or a comparison, you have to *know* what kind of object > you are treating. This fundamentally conflicts with pythons dynamic > nature. So basically, you want to add some behaviour to java objects used on the=20 python side. For that you will indeed need some support from jython. How about opening your script with: __javawrapper__ =3D yourWrappingClass ? yourWrappingClass is a python class that would be automatically instantia= ted=20 as a wrapper for every java object created. A java flagging interface wou= ld=20 not even needed. In case __javawrapper__ is not instantiated, the java wrapping behaviour=20 would default to the current behaviour. In principle, this also allows to remove the current behaviour from java = and=20 move it into eg. a built in __defaultjavawrapper__. You could than also extend the default wrapper: class yourWrappingClass(__defaultjavawrapper__): " define even nicer tricks using the default tricks " ... It looks and feels pythonic enough to me. Any thoughts? Ype |
From: Oti <oh...@ya...> - 2002-11-11 22:48:48
|
[ Ype Kingma ] > So basically, you want to add some behaviour to java objects used > on the python side. Exactly, and especially __setattr__/__getattr__ for accessing attributes which are not there at compile time, and __getattr__ to call methods which are not there at compile time. (We already have seen arithmetic and comparison operators in previous examples). > For that you will indeed need some support from jython. That's what I found out and tried to implement and share with the developers. Now, what I'd like to do is to help to do it right for future versions of Jython. > How about opening your script with: > > __javawrapper__ = yourWrappingClass > > ? > yourWrappingClass is a python class that would be automatically > instantiated as a wrapper for every java object created. > A java flagging interface would not even needed. I think a flagging interface is needed, because the majority of java classes won't be part of this game. The interface is needed on the java side to keep track of these special classes, and in Jython for knowing where to enable the Special Methods. This is independent of the implementation: Even your __javawrapper__ would have to decide if it wants to wrap or not, or, as you say below, the code deciding to instantiate/not instantiate the wrapper: > In case __javawrapper__ is not instantiated, the java wrapping > behaviour would default to the current behaviour. > In principle, this also allows to remove the current behaviour > from java and > move it into eg. a built in __defaultjavawrapper__. Coming from the java side, I'd rather not replace java code by python code, more likely the other way round :-) (reading your next mail) As you and Brian pointed out, it could be solved using a pluggable python wrapper class. I personally would prefer an implementation completely in java. Maybe we could do both <smile> ? Now I am a little confused about what the *right* way is. Best wishes, Oti. __________________________________________________ Do you Yahoo!? U2 on LAUNCH - Exclusive greatest hits videos http://launch.yahoo.com/u2 |
From: Ype K. <yk...@xs...> - 2002-11-13 21:38:34
|
Oti, <snip> > > How about opening your script with: > > > > __javawrapper__ =3D yourWrappingClass > > > > ? > > yourWrappingClass is a python class that would be automatically > > instantiated as a wrapper for every java object created. > > A java flagging interface would not even needed. > > I think a flagging interface is needed, because the majority of java > classes won't be part of this game. The interface is needed on the java > side to keep track of these special classes, and in Jython for knowing > where to enable the Special Methods. This is independent of the > implementation: Even your __javawrapper__ would have to decide if it > wants to wrap or not, or, as you say below, the code deciding to > > instantiate/not instantiate the wrapper: > > In case __javawrapper__ is not instantiated, the java wrapping > > behaviour would default to the current behaviour. > > In principle, this also allows to remove the current behaviour > > from java and > > move it into eg. a built in __defaultjavawrapper__. It's probably better to define this wrapper as a function (much like=20 Py.java2py is a static method) than as a class, as I suggested above. > Coming from the java side, I'd rather not replace java code by python > code, more likely the other way round :-) (reading your next mail) > As you and Brian pointed out, it could be solved using a pluggable > python wrapper class. I personally would prefer an implementation > completely in java. Maybe we could do both <smile> ? > > Now I am a little confused about what the *right* way is. Since these special methods are defined for use _in_ the python language, I think that is where they should be used. Now, how is calling the special methods implemented for Python objects, i= e.=20 instantiations of the java class PyObject ? I don't know enough of this to compare it with the scheme sketched below, so it might be incompatible with the current situation. If this scheme ma= kes=20 little sense, please tell me. As I suggested above, a python wrapper (A) around java objects could be u= sed=20 to redirect the calls to java. (A) would be returned by __javawrapper__. The current implementation of jython also defines a proxy object (B) for = each=20 java object (C) accessible from python. I think we should find a good distribution of responsibilities between th= e=20 python wrapper (A) and this proxy object (B) The python wrapper (A) would take care of handling the special methods a= nd=20 redirecting them however it wants to the wrapped java objects, via (B). The proxy object (B) would then be responsible for mapping the python typ= es=20 to and from the java types and performing java method lookup and java=20 attribute lookup. I tried finding the source code for such proxies but I = only found PyProxy.java and PyReflectedFunction.java. Currently CollectionProxy's have the role of (A) as they redirect python=20 special methods to Collection objects. However, they are implemented in j= ava. Regards, Ype |
From: Samuele P. <ped...@bl...> - 2002-11-15 17:57:27
|
> > How about opening your script with: > > > > __javawrapper__ = yourWrappingClass > > > > ? the scope of such a directive would be per-module so this will not fly. A global register OTOH can work. But there are other design decisions related to new-style classes to take before tackling this. regards. |
From: Ype K. <yk...@xs...> - 2002-11-15 19:40:28
|
On Friday 15 November 2002 18:45, Samuele Pedroni wrote: > > > How about opening your script with: > > > > > > __javawrapper__ =3D yourWrappingClass > > > > > > ? > > the scope of such a directive would be per-module so this will not fly. > A global register OTOH can work. This had crossed my mind, too. One might make it part of the sys module instead. I think using the registry as Brian did would be more static tha= n=20 needed. > But there are other design decisions related to new-style classes to ta= ke > before tackling this. I'm getting curious. I did read up sometime ago on python's new style classes, but I think the issues there are too esoteric to have practical=20 influence on my programs. I do like to use multiple inheritance, but I don't like using diamond shaped inheritance graphs. Having said that, I'll probably run into such problems sooner than I thin= k. I thought that crossing the jython/java border would only depend on similar issues at the cpyhton/c border. However, there is no inheritance = on=20 the C side, so that simplifies things there, leaving a lot of design free= dom=20 for crossing the jython/java border. Regards, Ype P.S. Has our behaviour been passable (ahem)? |
From: Oti <oh...@ya...> - 2002-11-28 06:46:17
|
[ Samuele Pedroni ] > > > > How about opening your script with: > > > > > > __javawrapper__ = yourWrappingClass > > > > > > ? > > the scope of such a directive would be per-module so this will not > fly. > A global register OTOH can work. > > But there are other design decisions related to new-style classes to > take > before tackling this. Do I interpret you correctly: The implementation of Special Methods for java classes is difficult to separate from the implementation of new-style classes. So a try for Special Methods on the current code base would likely be thrown away ? Best wishes, Oti. __________________________________________________ Do you Yahoo!? Yahoo! Mail Plus - Powerful. Affordable. Sign up now. http://mailplus.yahoo.com |
From: Samuele P. <ped...@bl...> - 2002-11-28 12:37:37
|
From: "Oti" <oh...@ya...> > Do I interpret you correctly: > The implementation of Special Methods for java classes is difficult to > separate from the implementation of new-style classes. > So a try for Special Methods on the current code base would likely be > thrown away ? > honestly yes regards. |
From: Oti <oh...@ya...> - 2002-11-28 06:15:31
|
[ Ype Kingma ] > Since these special methods are defined for use _in_ the python > language, > I think that is where they should be used. *used* yes, definitely. Implementation is the question, though. > Now, how is calling the special methods implemented for Python > objects, ie. > instantiations of the java class PyObject ? That's the way I would have tried, but given Samuele's post I currently doubt if it is worth the effort *this* way (I'll ask him separately). > I don't know enough of this to compare it with the scheme sketched > below, > so it might be incompatible with the current situation. If this > scheme makes > little sense, please tell me. I really am not sure what makes sense. I try to comment from my point of view. > As I suggested above, a python wrapper (A) around java objects could > be used > to redirect the calls to java. (A) would be returned by > __javawrapper__. > > The current implementation of jython also defines a proxy object (B) > for each > java object (C) accessible from python. > > I think we should find a good distribution of responsibilities > between the > python wrapper (A) and this proxy object (B) or we have a specialized proxy object which knows if and what to delegate to java. > The python wrapper (A) would take care of handling the special > methods and > redirecting them however it wants to the wrapped java objects, via > (B). > > The proxy object (B) would then be responsible for mapping the python > types > to and from the java types and performing java method lookup and java > > attribute lookup. I tried finding the source code for such proxies > but I only > found PyProxy.java and PyReflectedFunction.java. IMHO if a java class wants to implement Special Methods, it should take care of types itself. Please note that in my implementation (using PyJavaClass) there was no need to explicitly convert types: They just 'arrived' correctly in my java class, e.g. for __eq__(), or __call__(). > Currently CollectionProxy's have the role of (A) as they redirect > python > special methods to Collection objects. However, they are implemented > in java. That's fine for me :-) So please apologize if this doesn't bring you any further. I'm afraid I am running out of arguments. Best wishes, Oti. __________________________________________________ Do you Yahoo!? Yahoo! Mail Plus - Powerful. Affordable. Sign up now. http://mailplus.yahoo.com |
From: Ype K. <yk...@xs...> - 2002-11-16 20:49:37
|
Hello, I submitted a comment on this bug on sourceforge, and I tried to add a java program to that comment, but I could not find a way to do that, so I'm posting the program here. The java program below mimics the python script posted with the bug in that it performs the same reflected method call as jython does, but it provides a bit more information about the exception thrown. Since a java program produces the exception, the problem is not with jython. The bug and my comment are here: http://sourceforge.net/tracker/index.php?func=3Ddetail&aid=3D628315&group= _id=3D12867&atid=3D112867 Below is the java program verifying that it's not a jython bug. It opens= =20 with the original jython script that shows the IllegalAccessException. I think the jython bug can be closed. I'll check and evt. report this to = Sun. Regards, Ype /* Java test program for jython bug 628315 (to be closed.) Wrapping an ArrayList in Collection.synchronizedList throws an unexpected IllegalAccessException when calling the relected remove() m= ethod on the wrapped ArrayList. This java program is more or less equivalent to the test script posted wi= th=20 the bug: import java l=3Djava.util.ArrayList() l.add("str") o=3Dl.remove(0) print "Removed ", o l=3Djava.util.Collections.synchronizedList(java.util.ArrayList()) l.add("str") o=3Dl.remove(0) # jython CVS 16 Nov 2002: IllegalAccessExcept= ion print "Removed ", o */ /* Running this program shows that all operations run normally, * while the test script above throws the indicated exception. * Also test doing the remove() using a reflected method, to make * sure that this is not a Java bug. */ import java.util.ArrayList; import java.util.List; import java.util.Collections; import java.lang.reflect.Method; import java.lang.reflect.InvocationTargetException; class test628315 { public static Object reflectedRemove(List l) { =09Method m; =09String methodName =3D "remove"; =09try { =09 m =3D l.getClass().getMethod(methodName, new Class[] {Integer.TYPE= }); =09} catch (NoSuchMethodException nsme) { =09 System.out.println(nsme.toString() + " " + l.getClass() + " " +=20 methodName); =09 return null; =09} =09System.out.println("Calling reflected method " + m.toString()); =09try { =09 return m.invoke(l, new Object[] {new Integer(0)}); =09} catch (IllegalAccessException iae) { =09 System.out.println(iae.toString() + " " + l.getClass() + " " +=20 methodName); =09 return null; =09} catch (InvocationTargetException ite) { =09 System.out.println(ite.toString() + " " + l.getClass() + " " +=20 methodName); =09 return null; =09} } public static void test1(List l, String s) { =09l.add(s + " direct"); =09System.out.println("Removed " + l.remove(0).toString()); } public static void test2(List l, String s) { =09l.add(s + " reflected"); =09Object rmo =3D reflectedRemove(l);=20 =09if (rmo !=3D null) { =09 System.out.println("Removed " + rmo.toString()); =09} } public static void main(String[] args) { test1( new ArrayList(), "1"); test2( new ArrayList(), "2"); test1( Collections.synchronizedList(new ArrayList()), "3"); test2( Collections.synchronizedList(new ArrayList()), "4"); } } |
From: Ype K. <yk...@xs...> - 2002-11-16 21:04:03
|
Google revealed: http://www.jguru.com/faq/printablefaq.jsp?topic=3DCollections quoting from there: When I wrap a collection to be read-only or synchronized, why can't I cal= l=20 any of the collection methods via reflection without getting an=20 IllegalAccessException? Location: http://www.jguru.com/faq/view.jsp?EID=3D304724=20 Created: Jan 17, 2001 Modified: 2001-01-17 05:30:21.271 Author: John Zukowski (http://www.jguru.com/guru/viewbio.jsp?EID=3D7) Que= stion=20 originally posed by Brandon Wiley=20 (http://www.jguru.com/guru/viewbio.jsp?EID=3D304445=20 When you wrap a collection through the static methods of the Collections=20 class, this creates an instance of a package-private (default access) cla= ss.=20 Because you don't have access to these classes, you can't call their meth= ods=20 via reflection (though you can call their methods directly through the=20 appropriate interface).=20 end of quote. Does that mean that one can call these methods via reflection by casting to an appropriate interface in case of an IllegalAccessException? In that case it might make sense to add a search for such an interface to= =20 PyReflectedMethod.java when a first invocation gives an=20 IllegalAccessException. Regards, Ype |
From: Samuele P. <ped...@bl...> - 2002-11-16 21:13:38
|
From: "Ype Kingma" <yk...@xs...> >Does that mean that one can call these methods via reflection by casting >to an appropriate interface in case of an IllegalAccessException? >In that case it might make sense to add a search for such an interface to >PyReflectedMethod.java when a first invocation gives an >IllegalAccessException. yes, but is not a matter of backtracking, statically we know that it is pointless to call non-public classes method through reflection, we simply have to ignore them and consider instead the implemented public interfaces' ones. regards. |
From: Ype K. <yk...@xs...> - 2002-11-17 10:33:31
|
On Saturday 16 November 2002 22:01, Samuele Pedroni wrote: > From: "Ype Kingma" <yk...@xs...> > > >Does that mean that one can call these methods via reflection by casti= ng > >to an appropriate interface in case of an IllegalAccessException? > >In that case it might make sense to add a search for such an interface= to > >PyReflectedMethod.java when a first invocation gives an > >IllegalAccessException. > > yes, but is not a matter of backtracking, statically we know that it is > pointless to call non-public classes method through reflection, > we simply have to ignore them and consider instead the implemented publ= ic > interfaces' ones. And jython doesn't catch the IlegalAccessException because that would tak= e=20 more execution time? I'll try and extend the test program to check for private access and sear= ch=20 for evt. interfaces, on a next occasion. Regards, Ype P.S. It wasn't work for me, I just happened to have some spare time with=20 compulsory location close the computer... Btw. I did not post the bug. |