Prev         Up         Next

Proxy objects

A proxy is an object which refers to a shared object which lives (presumably) in a different process. The shared object is said to be the referent of the proxy. Multiple proxy objects may have the same referent.

A proxy object has methods which invoke corresponding methods of its referent (although not every method of the referent will necessarily be available through the proxy). A proxy can usually be used in most of the same ways that the its referent can:

>>> from processing import Manager
>>> manager = Manager()
>>> l = manager.list([i*i for i in range(10)])
>>> print l
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> print repr(l)
<Proxy[list] object at 0x00DFA230>
>>> l[4]
16
>>> l[2:5]
[4, 9, 16]
>>> l == [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
True

Notice that applying str() to a proxy will return the representation of the referent, whereas applying repr() will return the representation of the proxy.

An important feature of proxy objects is that they are picklable so they can be passed between processes. Note, however, that if a proxy is sent to the corresponding manager's process then unpickling it will produce the referent itself. This means, for example, that one shared object can contain a second:

>>> a = manager.list()
>>> b = manager.list()
>>> a.append(b)         # referent of `a` now contains referent of `b`
>>> print a, b
[[]] []
>>> b.append('hello')
>>> print a, b
[['hello']] ['hello']

Some proxy methods return a proxy for an iterator. In particular list and dictionary proxies are iterables so they can be used with the for statement:

>>> a = manager.dict([(i*i, i) for i in range(10)])
>>> for key in a:
...     print '<%r,%r>' % (key, a[key]),
...
<0,0> <1,1> <4,2> <81,9> <64,8> <9,3> <16,4> <49,7> <25,5> <36,6>

Note

Although list and dict proxy objects are iterable, it will be much more efficient to iterate over a copy of the referent, for example

for item in some_list[:]:
    ...

and

for key in some_dict.keys():
    ...

Methods of BaseProxy

Proxy objects are instances of subclasses of BaseProxy. The only semi-public methods of BaseProxy are the following:

_callMethod(methodname, args=(), kwds={})

Call and return the result of a method of the proxy's referent.

If proxy is a proxy whose referent is obj then the expression

proxy._callMethod(methodname, args, kwds)

will evaluate the expression

getattr(obj, methodname)(*args, **kwds)         (*)

in the manager's process.

The returned value will be either a copy of the result of (*) or if the result is an unpicklable iterator then a proxy for the iterator.

If an exception is raised by (*) then then is re-raised by _callMethod(). If some other exception is raised in the manager's process then this is converted into a RemoteError exception and is raised by _callMethod().

Note in particular that an exception will be raised if methodname has not been exposed --- see the exposed argument to CreatorMethod.

_getValue()

Return a copy of the referent.

If the referent is unpicklable then this will raise an exception.

__repr__
Return a representation of the proxy object.
__str__
Return the representation of the referent.

Cleanup

A proxy object uses a weakref callback so that when it gets garbage collected it deregisters itself from the manager which owns its referent.

A shared object gets deleted from the manager process when there are no longer any proxies referring to it.

Examples

An example of the usage of _callMethod():

>>> l = manager.list(range(10))
>>> l._callMethod('__getslice__', (2, 7))   # equiv to `l[2:7]`
[2, 3, 4, 5, 6]
>>> l._callMethod('__iter__')               # equiv to `iter(l)`
<Proxy[iter] object at 0x00DFAFF0>
>>> l._callMethod('__getitem__', (20,))     # equiv to `l[20]`
Traceback (most recent call last):
...
IndexError: list index out of range

As an example definition of a subclass of BaseProxy, the proxy type used for iterators is the following:

class IteratorProxy(BaseProxy):
    def __iter__(self):
        return self
    def next(self):
        return self._callMethod('next')