Skip to content
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

Make Proxy/foreign objects operate like their Python equivalents #248

Open
aeriksson opened this issue Dec 10, 2021 · 1 comment
Open

Make Proxy/foreign objects operate like their Python equivalents #248

aeriksson opened this issue Dec 10, 2021 · 1 comment

Comments

@aeriksson
Copy link

As it stands, the usefulness of Proxy objects as passed to Python is somewhat limited. They all map to the foreign class, and AFAICT there's often no way to tell them apart short of randomly attempting to call methods that are known to behave differently for different Proxy classes and seeing if/which exceptions are thrown.

I'm passing 'simple' data structures (i.e. ones that can be JSON-serialized) to Python from Java as Proxy objects, and I'd like these to behave like 'normal' Python objects (ideally they should be indistinguishable from what I'd get by JSON-serializing the data in Java and calling json.loads() on it in Python). To get this behavior currently, I have to manually eval some Python translation code (which some iffy exception-based 'type checks' as outlined above) to replace the foreign values with proper Python equivalents. Since this has to happen both for bindings and function (ProxyExecutable) return values, it ends up complicating my code quite a bit, as well as slowing things down.

I wouldn't have to do any of this work if the Proxy types acted as their corresponding Python builtins by default. It seems to me like:

  • ProxyHashMap should act as a dict.
  • ProxyArray should act as an array.
  • ProxyObject should act as a plain old class.

Since Python is duck-typed, it should be relatively straightforward to make these types act as their Python equivalents by simply implementing the relevant attributes.

Looking at the built-in attributes of the aforementioned Python types, we see (Python 3.9.7):

> dir({})
['__class__', '__class_getitem__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__ior__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__or__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__ror__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']

> dir([])
['__add__', '__class__', '__class_getitem__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

> class Foo(): pass
> dir(Foo())
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']

For the Proxy types, dir() returns nothing (except for ProxyObject, where it returns the provided methods but none of the __ attributes). (It seems like some of these methods are still implemented (so __dir__ isn't working quite right) — for example __str__ works as expected for ProxyArray, and it exists for ProxyHashMap but doesn't print the actual map.)

Implementing (most of) these functions on the relevant proxy objects doesn't seem like it'd be that difficult, and would go a long way towards making graalpython more user-friendly!

P.S. thanks for this awesome project!

@eregon
Copy link
Member

eregon commented Aug 22, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants