-
Notifications
You must be signed in to change notification settings - Fork 186
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor JImplements as a metaclass #770
Comments
I plan to review this once I have support to class extensions. I am not sure that meta class is a good idea as it implies something else. I was planning to make it work with
This is much more clear as the Python class would have a presence as an Object and would get the interfaces. We could also do
with some effort. But I believe we can't do so until we drop support for Python 3.5. We have a meta class (_jpype._JClass) which can process the implements list and create the correct proxy implementation. |
Won't just class MyClass(interface1, interface2):
... be better? |
I am not sure that I can do that. It is true that anything that inherits from a Java object gets the _JClass meta. I am not sure that I can properly enforce the extends first implements second. But perhaps you are correct. I will play with this when I have the ability to extends a class. Perhaps I can make it that simple. |
I am going to put this on the long term enhancement list as I can't really do much with it prior to the release. |
Looking at the refactoring for extensions I believe I will be able to grant this one. Though there are some implications that I should run by you. Currently when we implement an interface the object that we are creating is based in Python and thus when passed as proxy unpacks to a Python object as "self"
If we implement a Java class (or extend one), then the instance is just stealing the methods and thus any instances that we create will be Java handles which point to Python methods. This means that the first argument is a Java object instance. There is no actual Python object associated with it. It is simply a Java class that will call Python methods. The class will be closed and any slots must be declared with a type and access restrictions.
Does this seem usable? |
IDK for now. First of all,
is completely OK. And probably that can be done implicitly by defaulting to But I don't quite understand what
means. Does it mean that it would be impossible to create a class with additional fields/methods? If so, it feels like that such classes will almost always be useless (though it may be possible to workaround that with much perversions, such as a global |
I put down a pretty good explanation of this in the "doc/extensions.rst". By closed I mean just like Java classes they cannot be altered after they are defined. Thus the methods and fields that they have can only be defined when the class definition is parsed as opposed to Python classes where attributes and methods can be added even after the class if defined (or even on the fly as it is used.) Here is a quick example
Basically this allows you to make a new Java class from within Python with the added capability that it automatically proxies so you can call Python code directly. It just compiles it on the fly into a new Java class. I can try to give it a dictionary, add storage for Python fields, or generate more native like behavior later, but those will have significant down sides in terms of potential memory leaks and other dangerous side effects. Do these restrictions appear reasonable? |
strangely, I haven't found this doc. Also, IDK where epypj repo resides.
That is OK as long as a user can add a collection to store the data it doesn't know beforehand.
Does it mean that we will have inheritance too?
The primary here is storage for python-native objects. It seems it can be implemented even without built-in support, if storage = {}
class MyExtension(JObject):
@JPublic
def __init__(self, s:String):
storage[id(self)] = {"s": s}
@JPublic
def __del__(self):
del storage[id(self)] |
The extension and epypj are branches on the Thrameos/jpype fork. I do a lot of my advanced work there are then push it over when it is ready. Of course if I haven't pushed it, it likely does not work. The doc/extension.rst is attached to the PR for extensions.
Well I can potentially let someone do something like
But that requires that I implement enough of epypj to make is so that the Java type PyDict is recognizable. You can also just use The danger comes if someone attempts the following.
Yes, you can inherit from one extension to another in Python. You can also use reflecting in Java to call any of the newly defined methods. It automatically names classes using the Even if I don't define it explicitly you can always add a dictionary or store arbitrary data using the existing Proxy. The interfaces 'java.io.Serializable' (or any interface with no methods) can be used to export Python object into Java. JProxy with the dict keyword will store a dictionary in Java. I plan to hook that up to the cast operation for "(java)@obj" which would look at the type. If it is already Java then nothing happens it just returns the object. But it it is a Python object you would get a Java PyObject (inherited from java.lang.Object) instance which holds a reference to the Python object. You can then unwrap it to get back the Python instance. (it unpacks automatically when accessing as a field or argument in a proxy). This is useful to do things like putting Python objects onto Java collection like ArrayList. It is currently supported using some magic with JProxy but I need to formalize it into a usable feature. Again there are dangers for memory leaks until we add support to allow Python Of course porting PyPy using libffi and JAS to implement a full CPython API and add reference counting support into Java using an agent so that Python can run at native Java speeds and recycle memory for reasonable performance is also possible but I doubt anyone has the time to pull such a thing off. I suspect getting Graalvm up to par would be less effort. |
It is not quite a true metaclass (true metaclass has caused an error), but is interfaced like it:
so it can be used as
Why is it needed? I feel like it may allow some compatibility to the impls (i.e. Jython and probably GraalVM in future, currently it cannot implement Java interfaces or inherit Java classes) where implementing an interface is done via simple inheritance from it. So, to change an impl, one has only to change the set of classes and metaclasses. I have a lib https://github.com/KOLANICH/JAbs.py for this.
The text was updated successfully, but these errors were encountered: