[pypy-svn] r39730 - in pypy/dist/pypy/lib/distributed: . test
fijal at codespeak.net
fijal at codespeak.net
Fri Mar 2 18:06:54 CET 2007
Author: fijal
Date: Fri Mar 2 18:06:52 2007
New Revision: 39730
Modified:
pypy/dist/pypy/lib/distributed/objkeeper.py
pypy/dist/pypy/lib/distributed/protocol.py
pypy/dist/pypy/lib/distributed/test/test_distributed.py
Log:
Make classmethods work remotely
Modified: pypy/dist/pypy/lib/distributed/objkeeper.py
==============================================================================
--- pypy/dist/pypy/lib/distributed/objkeeper.py (original)
+++ pypy/dist/pypy/lib/distributed/objkeeper.py Fri Mar 2 18:06:52 2007
@@ -11,18 +11,18 @@
_, _, tb = sys.exc_info()
GetSetDescriptor = type(type(tb).tb_frame)
-class noninstantiabletype(object):
- def __new__(cls, *args, **kwargs):
- raise NotImplementedError("Cannot instantiate remote type")
+class RemoteBase(object):
+ pass
class ObjKeeper(object):
def __init__(self, exported_names = {}):
self.exported_objects = [] # list of object that we've exported outside
self.exported_names = exported_names # dictionary of visible objects
- self.exported_types = {} # list of exported types
+ self.exported_types = {} # dict of exported types
self.remote_types = {}
self.remote_objects = {}
self.exported_types_id = 0 # unique id of exported types
+ self.exported_types_reverse = {} # reverse dict of exported types
def register_object(self, obj):
# XXX: At some point it makes sense not to export them again and again...
@@ -30,7 +30,7 @@
return len(self.exported_objects) - 1
def ignore(self, key, value):
- if key in ('__dict__', '__weakref__', '__class__', '__new__'):
+ if key in ('__dict__', '__weakref__', '__class__'):
return True
if isinstance(value, GetSetDescriptor):
return True
@@ -42,6 +42,7 @@
except KeyError:
print "Registering type %s as %s" % (tp, self.exported_types_id)
self.exported_types[tp] = self.exported_types_id
+ self.exported_types_reverse[self.exported_types_id] = tp
tp_id = self.exported_types_id
self.exported_types_id += 1
@@ -56,15 +57,21 @@
def fake_remote_type(self, protocol, type_id, _name, _dict):
print "Faking type %s as %s" % (_name, type_id)
# create and register new type
- d = dict([(key, None) for key in _dict if key != '__new__'])
+ d = dict([(key, None) for key in _dict])
+ # some stuff needs to go first...
if '__doc__' in _dict:
d['__doc__'] = protocol.unwrap(_dict['__doc__'])
- tp = type(_name, (noninstantiabletype,), d)
+ tp = type(_name, (RemoteBase,), d)
+ tp.__metaremote__ = type_id
# Make sure we cannot instantiate the remote type
self.remote_types[type_id] = tp
for key, value in _dict.items():
if key != '__doc__':
setattr(tp, key, protocol.unwrap(value))
+ #elif key == '__new__':
+ # import pdb
+ # pdb.set_trace()
+ # tp.new = value
def get_type(self, id):
return self.remote_types[id]
Modified: pypy/dist/pypy/lib/distributed/protocol.py
==============================================================================
--- pypy/dist/pypy/lib/distributed/protocol.py (original)
+++ pypy/dist/pypy/lib/distributed/protocol.py Fri Mar 2 18:06:52 2007
@@ -41,7 +41,7 @@
except ImportError:
raise ImportError("Cannot work without transparent proxy functionality")
-from distributed.objkeeper import ObjKeeper
+from distributed.objkeeper import ObjKeeper, RemoteBase
import sys
# XXX We do not make any garbage collection. We'll need it at some point
@@ -91,6 +91,7 @@
'tp' : None,
'fr' : types.FrameType,
'tb' : types.TracebackType,
+ 'reg' : RemoteBase
}
type_letters = dict([(value, key) for key, value in letter_types.items()])
assert len(type_letters) == len(letter_types)
@@ -131,6 +132,10 @@
id = self.keeper.register_object(obj)
return (self.type_letters[tp], id)
elif tp is type:
+ if isinstance(obj, RemoteBase):
+ import pdb
+ pdb.set_trace()
+ return "reg", obj.__metaremote__
try:
return self.type_letters[tp], self.type_letters[obj]
except KeyError:
@@ -156,6 +161,8 @@
tp = self.letter_types[tp_letter]
if tp is None:
return self.keeper.get_object(obj_data)
+ elif tp is RemoteBase:
+ return self.keeper.exported_types_reverse[obj_data]
elif tp in self.immutable_primitives:
return obj_data # this is the object
elif tp is tuple:
@@ -179,6 +186,9 @@
name = self.unwrap(w_name)
self_ = self.unwrap(w_self)
if self_:
+ if not tp:
+ setattr(self_, name, classmethod(self.unwrap(w_func)))
+ return getattr(self_, name)
return getattr(tp, name).__get__(self_, tp)
func = self.unwrap(w_func)
setattr(tp, name, func)
@@ -368,4 +378,13 @@
inp, out = channel(), channel()
remote_protocol = RemoteProtocol(inp.send, out.receive, exported_names)
t = tasklet(remote_loop)(remote_protocol)
- return RemoteProtocol(out.send, inp.receive)
+
+ def send_trace(data):
+ print "Sending %s" % (data,)
+ out.send(data)
+
+ def receive_trace():
+ data = inp.receive()
+ print "Received %s" % (data,)
+ return data
+ return RemoteProtocol(send_trace, receive_trace)
Modified: pypy/dist/pypy/lib/distributed/test/test_distributed.py
==============================================================================
--- pypy/dist/pypy/lib/distributed/test/test_distributed.py (original)
+++ pypy/dist/pypy/lib/distributed/test/test_distributed.py Fri Mar 2 18:06:52 2007
@@ -198,11 +198,25 @@
else:
raise AssertionError("Did not raise")
+ def test_remote_classmethod(self):
+ class A:
+ z = 8
+
+ @classmethod
+ def x(cls):
+ return cls.z
+
+ a = A()
+ protocol = self.test_env({'a':a})
+ xa = protocol.get_remote("a")
+ res = xa.x()
+ assert res == 8
+
def test_instantiate_remote_type(self):
- #skip("Land of infinite recursion")
+ skip("Doesn't work yet")
class C:
pass
protocol = self.test_env({'C':C})
xC = protocol.get_remote('C')
- raises(NotImplementedError, "xC()")
+ xC()
More information about the pypy-svn
mailing list