[pypy-svn] r42197 - in pypy/dist/pypy/lib/distributed: . test

fijal at codespeak.net fijal at codespeak.net
Fri Apr 20 11:10:46 CEST 2007


Author: fijal
Date: Fri Apr 20 11:10:44 2007
New Revision: 42197

Added:
   pypy/dist/pypy/lib/distributed/faker.py
      - copied unchanged from r42196, pypy/branch/lib-distributed-rewrite/pypy/lib/distributed/faker.py
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:
Hum, history has gone. Anyway:

* Added better type faker which is able to fake descriptors
* Fixed few bugs
* Added few tests
* Now we cannot instantiate remote type as long as we don't
  take care for remote basis, but more faking works.


Modified: pypy/dist/pypy/lib/distributed/objkeeper.py
==============================================================================
--- pypy/dist/pypy/lib/distributed/objkeeper.py	(original)
+++ pypy/dist/pypy/lib/distributed/objkeeper.py	Fri Apr 20 11:10:44 2007
@@ -2,19 +2,8 @@
 """ objkeeper - Storage for remoteprotocol
 """
 
-# XXX jeez
-
-import sys
-try:
-    1/0
-except:
-    _, _, tb = sys.exc_info()
-    GetSetDescriptor = type(type(tb).tb_frame)
-
-class RemoteBase(object):
-    pass
-
 from types import FunctionType
+from distributed import faker
 
 class ObjKeeper(object):
     def __init__(self, exported_names = {}):
@@ -33,9 +22,10 @@
         return len(self.exported_objects) - 1
     
     def ignore(self, key, value):
-        if key in ('__dict__', '__weakref__', '__class__'):
-            return True
-        if isinstance(value, GetSetDescriptor):
+        # there are some attributes, which cannot be modified later, nor
+        # passed into default values, ignore them
+        if key in ('__dict__', '__weakref__', '__class__',
+                   '__dict__', '__bases__'):
             return True
         return False
     
@@ -43,43 +33,22 @@
         try:
             return self.exported_types[tp]
         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
-        
-        # XXX: We don't support inheritance here, nor recursive types
-        #      shall we???
-        _dict = dict([(key, protocol.wrap(getattr(tp, key))) for key in dir(tp) 
-            if not self.ignore(key, getattr(tp, key))])
-        protocol.send(("type_reg", (tp_id, 
-            tp.__name__, _dict)))
+
+        protocol.send(('type_reg', faker.wrap_type(protocol, tp, tp_id)))
         return tp_id
     
-    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])
-        # some stuff needs to go first...
-        if '__doc__' in _dict:
-            d['__doc__'] = protocol.unwrap(_dict['__doc__'])
-        tp = type(_name, (RemoteBase,), d)
-        # Make sure we cannot instantiate the remote type
+    def fake_remote_type(self, protocol, tp_data):
+        type_id, name_, dict_w, bases_w = tp_data
+        tp = faker.unwrap_type(self, protocol, type_id, name_, dict_w, bases_w)
+
+    def register_remote_type(self, tp, type_id):
         self.remote_types[type_id] = tp
         self.reverse_remote_types[tp] = type_id
-        for key, value in _dict.items():
-            if key != '__doc__':
-                v = protocol.unwrap(value)
-                if isinstance(v, FunctionType):
-                    setattr(tp, key, staticmethod(v))
-                else:
-                    setattr(tp, key, v)
-            #elif key == '__new__':
-            #    import pdb
-            #    pdb.set_trace()
-            #    tp.new = value
-                    
+    
     def get_type(self, id):
         return self.remote_types[id]
 
@@ -91,3 +60,4 @@
 
     def get_remote_object(self, controller):
         return self.remote_objects[controller]
+        

Modified: pypy/dist/pypy/lib/distributed/protocol.py
==============================================================================
--- pypy/dist/pypy/lib/distributed/protocol.py	(original)
+++ pypy/dist/pypy/lib/distributed/protocol.py	Fri Apr 20 11:10:44 2007
@@ -41,7 +41,8 @@
 except ImportError:
     raise ImportError("Cannot work without transparent proxy functionality")
 
-from distributed.objkeeper import ObjKeeper, RemoteBase
+from distributed.objkeeper import ObjKeeper
+from distributed import faker
 import sys
 
 # XXX We do not make any garbage collection. We'll need it at some point
@@ -62,6 +63,17 @@
 from marshal import dumps
 import exceptions
 
+# just placeholders for letter_types value
+class RemoteBase(object):
+    pass
+
+class DataDescriptor(object):
+    pass
+
+class NonDataDescriptor(object):
+    pass
+# end of placeholders
+
 class AbstractProtocol(object):
     immutable_primitives = (str, int, float, long, unicode, bool, types.NotImplementedType)
     mutable_primitives = (list, dict, types.FunctionType, types.FrameType, types.TracebackType,
@@ -91,7 +103,9 @@
         'tp' : None,
         'fr' : types.FrameType,
         'tb' : types.TracebackType,
-        'reg' : RemoteBase
+        'reg' : RemoteBase,
+        'get' : NonDataDescriptor,
+        'set' : DataDescriptor,
     }
     type_letters = dict([(value, key) for key, value in letter_types.items()])
     assert len(type_letters) == len(letter_types)
@@ -132,8 +146,10 @@
             id = self.keeper.register_object(obj)
             return (self.type_letters[tp], id)
         elif tp is type:
-            if issubclass(obj, RemoteBase):
+            try:
                 return "reg", self.keeper.reverse_remote_types[obj]
+            except KeyError:
+                pass
             try:
                 return self.type_letters[tp], self.type_letters[obj]
             except KeyError:
@@ -196,6 +212,10 @@
                 return self.letter_types[obj_data]
             id = obj_data
             return self.get_type(obj_data)
+        elif tp is DataDescriptor:            
+            return faker.unwrap_getset_descriptor(self, obj_data)
+        elif tp is NonDataDescriptor:
+            return faker.unwrap_get_descriptor(self, obj_data)
         elif tp is object:
             # we need to create a proper type
             w_tp, id = obj_data
@@ -286,8 +306,7 @@
             exc, val, tb = unwrap(data)
             raise exc, val, tb
         elif command == 'type_reg':
-            type_id, name, _dict = data
-            protocol.keeper.fake_remote_type(protocol, type_id, name, _dict)
+            protocol.keeper.fake_remote_type(protocol, data)
         elif command == 'force':
             obj = protocol.keeper.get_object(data)
             w_obj = protocol.pack(obj)
@@ -295,6 +314,17 @@
         elif command == 'forced':
             obj = protocol.unpack(data)
             return obj
+        elif command == 'desc_get':
+            name, w_obj, w_type = data
+            obj = protocol.unwrap(w_obj)
+            type_ = protocol.unwrap(w_type)
+            send(('finished', protocol.wrap(getattr(type(obj), name).__get__(obj, type_))))
+        elif command == 'desc_set':
+            name, w_obj, w_value = data
+            obj = protocol.unwrap(w_obj)
+            value = protocol.unwrap(w_value)
+            getattr(type(obj), name).__set__(obj, value)
+            send(('finished', protocol.wrap(None)))
         else:
             raise NotImplementedError("command %s" % command)
 
@@ -347,6 +377,14 @@
         else:
             raise NotImplementedError("Cannot unpack %s" % (data,))
 
+    def get(self, name, obj, type):
+        self.send(("desc_get", (name, self.wrap(obj), self.wrap(type))))
+        retval = remote_loop(self)
+        return retval
+
+    def set(self, obj, value):
+        self.send(("desc_set", (name, self.wrap(obj), self.wrap(value))))
+
 class RemoteObject(object):
     def __init__(self, protocol, id):
         self.id = id

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 Apr 20 11:10:44 2007
@@ -219,8 +219,19 @@
         res = xa.x()
         assert res == 8
 
+    def test_types_reverse_mapping(self):
+        class A:
+            def m(self, tp):
+                assert type(self) is tp
+
+        a = A()
+        protocol = self.test_env({'a':a, 'A':A})
+        xa = protocol.get_remote('a')
+        xA = protocol.get_remote('A')
+        xa.m(xA)
+
     def test_instantiate_remote_type(self):
-        #skip("Doesn't work yet")
+        skip("Will not work unless we take care about __basis__")
         class C:
             def __init__(self, y):
                 self.y = y
@@ -230,6 +241,24 @@
 
         protocol = self.test_env({'C':C})
         xC = protocol.get_remote('C')
-        res = xC(3).x()
+        xc = xC(3)
+        res = xc.x()
         assert res == 3
 
+    def test_remote_sys(self):
+        import sys
+
+        protocol = self.test_env({'sys':sys})
+        s = protocol.get_remote('sys')
+        l = dir(s)
+        assert l
+
+    def test_remote_file_access(self):
+        # cannot do test_env({'file':file}) yet :)
+        def f(name):
+            return open(name)
+
+        protocol = self.test_env({'f':f})
+        xf = protocol.get_remote('f')
+        data = xf('/etc/passwd').read()
+        assert data



More information about the Pypy-commit mailing list