irmen / Pyro5

Pyro 5 - Python remote objects
https://pyro5.readthedocs.io
MIT License
303 stars 36 forks source link

Proxy does not expose some special methods correctly #44

Closed eudoxos closed 2 years ago

eudoxos commented 3 years ago

Some special methods, such as __len__ or __getitem__ do not go through __getattr__ when called via their special syntax: len(a) will not look for __len__ using __getattr__ (but a.__len__ will use __getattr__), just like a[0] (vs. a.__getitem__) .

Python documentation on Special method lookup says in the last paragraph:

Bypassing the __getattribute__() machinery in this fashion provides significant scope for speed optimisations within the interpreter, at the cost of some flexibility in the handling of special methods (the special method must be set on the class object itself in order to be consistently invoked by the interpreter).

Pyro5 documentation says:

You can expose a ‘dunder’ method with double underscore for example __len__.

which however does not work as expected — the special syntax such as len(a) will not work.

The solution would be to define those few special methods on the Proxy class itself, and have them raise an exception if they are not really exposed by the proxy.

A case in the point is here which uses the workaround of explicit __getitem__:

self.assertEqual(root.__getitem__(0).getMolecules().__getitem__(0).getAtoms().__getitem__(0).getIdentity().getElement(),'Q')
irmen commented 2 years ago

Regarding iteration over a proxy, note that it is possible already to return an iterator object from a pyro method. https://pyro5.readthedocs.io/en/latest/clientcode.html?highlight=streaming#remote-iterators-generators

Regarding exposing the dunder methods, the documentation is correct in the sense that these methods can be exposed via Pyro ( 'private' methods starting with underscores are normally not remotely accessible). However actually calling them via special functions seems to not work as expected. I'll look into that (and pr #45 )

irmen commented 2 years ago

I've rewritten the iter implementation.