0

I am trying make a pyro4 proxy indexable. To test this, I took the greeting example from http://pythonhosted.org/Pyro4/intro.html#simple-example and I modified it:

Server:

import Pyro4

class Test(object):

    def __getitem__(self, index):
        return index

test = Test()
print test[1]
print test[100]


daemon = Pyro4.Daemon()
uri = daemon.register(test)


print("Ready. Object uri =", uri)
daemon.requestLoop()

Client:

import Pyro4

uri = input("What is the Pyro uri of the object? ").strip()

test = Pyro4.Proxy(uri)
print test.__getitem__(1)
print test.__getitem__(100)

print test[1]
print test[100]

The [] notation works on the server, but not also on the client proxy. I get:

TypeError: 'Proxy' object does not support indexing

But calls directly to __getitem__ do work.

andi
  • 912
  • 1
  • 10
  • 25

2 Answers2

1

I've just run into this myself.

From what I can see looking at the source code, Pyro4 doesn't proxy the Python implicit __getitem__ call that index notation uses. It does proxy __getattr__, which is why calling the __getitem__ method directly works.

What you can do, though, is create (on the client side) a proxy to the Pyro proxy(!) that implements __getitem__ and lets all other method calls fall through:

class TestProxy(object):
    def __init__(self, pyroTest):
        self.pyroTest = pyroTest

    def __getattr__(self, name):
        return getattr(self.pyroTest, name)

    def __getitem__(self, item):
        return self.pyroTest.__getitem__(item)

Then you can use index notation on the TestProxy object, as well as call methods in the normal Pyro way.

(Disclaimer: there are probably all sorts of Pythonic edge cases that this simple solution fails to cover!)

This might be worth an enhancement request for Pyro.

James Muscat
  • 454
  • 3
  • 5
  • This indeed works. But I see the problem more in Python itself then in Pyro. I would expect a[0] to be just a syntactic sugaring around a._ getitem _ (0). Instead of that, there seems to be code that checks if _ getitem _ exists in the dictionary. And this, probably, just to make the error message fancier: object not indexable instead of _ getitem _ not defined. – andi Nov 04 '15 at 12:54
1

While this could perhaps be added to the Pyro proxy, it actually promotes potentially horrible performing code. Indexing an object usually is done because the object is a collection of some sort and you are probably iterating over it. Doing this on a Pyro proxy will result in terrible performance because every index lookup will be a remote call. It is usually a lot faster and way more efficient to simply get the collection you want to iterate over all at once using one remote call, and then iterate over the resulting local object as usual. YMMV, it depends on the situation ofcourse.

Irmen de Jong
  • 2,739
  • 1
  • 14
  • 26
  • For the case I initially wanted this feature I have very few items in the list. But I wanted a transparent mirror in a different process: changing the proxy would cause the original object to be changed. I gave up and now I send a copy and offer as API functions for changing the list. So although I use now what you propose in this answer, the other answer answers my original question. – andi Nov 15 '15 at 06:08