Example #1
0
    def record(self, data):
        cls = data.__class__

        if self.auto_proxy is not None:
            path = self.auto_proxy(data)
            if path is not None:
                return self._autoProxy(path, data)

        ref = getattr(data, 'ref', None)
        if type(ref) is Ref:
            data = ref

        if hasattr(data, '_ext_encoding'):
            return data._ext_encoding()

        serialize = getattr(cls, 'serialize', None)
        if type(serialize) is tuple:
            name = cls.__name__
            value = []
            for key in serialize:
                if key.startswith('#'):
                    raise SerializationError('local resources used: ' +
                                             cls.__name__)
                value.append(getattr(data, key, None))
            return name, value

        raise SerializationError('cannot serialize: ' + cls.__name__)
Example #2
0
 def delocalize(self, x):
     # This is what we call for sending things to a different thread.
     # It is only applied to leaf nodes (via rmap).
     # rmap copies but it should actually be possible to change
     # only the leaf nodes that need to change because while a call
     # is in progress nothing can happen to variables referenced
     # only in the suspended stack-frame. If variables are added to
     # self then it would be possible for a call to access them
     # from the original vat's thread at the same time that they are
     # being accessed in the other thread.
     if isinstance(x, Exception):
         return x
     typ = type(x)
     if typ in POD_TYPES:
         return x
     if typ is Proxy:
         return Proxy(x._node, x._path)
     if typ is not Ref:
         try:
             ref = x.ref
         except AttributeError:
             pass
         else:
             # Should we be checking in case ref is not a Ref?
             if type(ref) is Ref:
                 x = ref
                 typ = Ref
             else:
                 print 'unexpected .ref attribute', repr(x), x.ref
     if typ is Ref:
         return Proxy(self.node_id, x._path)
     raise SerializationError('cannot delocalize type %s' % typ)
Example #3
0
    def record(self, inst):
        t = type(inst)
        if isinstance(inst, Exception):
            return 'exc', encodeException(inst)
        ref = getattr(inst, 'ref', None)
        if type(ref) is Ref:
            t, inst = Ref, ref
        if t is Ref and not inst._facet:
            # TODO: make a slot property for storing facet ref slots.
            return 'ref', {'path': inst._path, 'node': self.node_id}
        if t is Proxy:
            return 'ref', {'path': inst._path, 'node': inst._node}

        # Serialize instances without any capability members.
        s_attrs = getattr(t, 'serialize', None)
        if type(s_attrs) is tuple and not [
                a for a in s_attrs if a.startswith('_')
        ]:
            data = dict([(key.lstrip('_'), getattr(inst, key))
                         for key in s_attrs])
            cls = inst.__class__
            data['CLS'] = '%s.%s' % (cls.__module__, cls.__name__)
            return 'inst', data

        raise SerializationError(str(t))
Example #4
0
    def custom(self, name, value):
        # FIXME: have we set up the full serializability code
        # below only to use hooks here instead for stuff like QTerm?

        if name in self.hooks:
            return self.hooks[name](self.rpc(), value)

        if not self._safe_cls(name):
            raise SerializationError('Unsafe type: ' + name)

        cls = importSymbol(name)
        try:
            args = [value[key] for key in cls.serialize]
        except KeyError:
            raise SerializationError(name + ': ' + repr(data))
        else:
            return cls(*args)
Example #5
0
 def localize(self, x):
     if isinstance(x, Exception):
         return x
     typ = type(x)
     if typ in POD_TYPES:
         return x
     if typ is Proxy:
         if x._node == self.node_id:
             return Ref(self.storage, x._path)
         return Proxy(x._node, x._path, self)
     raise SerializationError('cannot localize type %s' % typ)
Example #6
0
    def custom(self, name, data):
        if name == 'ref':
            node = data['node']
            if node == self.node_id:
                return Ref(self.vat().storage, data['path'])
            if node == '-':
                node = self.msg_data.get('from')
            return Proxy(node, data['path'], self.vat())
        if name == 'exc':
            return decodeException(data)

        if name == 'inst' and self._safe_cls(data['CLS']):
            cls = importSymbol(data['CLS'])
            try:
                args = [data[key.lstrip('_')] for key in cls.serialize]
            except KeyError:
                raise SerializationError(name + ': ' + repr(data))
            else:
                return cls(*args)

        raise SerializationError(name)
Example #7
0
 def record(self, inst):
     cls = type(inst)
     # Replace any instance having a slot somewhere with its Ref.
     ref = getattr(inst, 'ref', None)
     if type(ref) is Ref and ref._path != self.path:
         cls, inst = Ref, ref
     if cls is Ref:
         data = {'path': inst._path}
         if inst._facet:
             data['facet'] = inst._facet
         return 'ref', data
     if type(getattr(cls, 'serialize', None)) is tuple:
         data = getDict(inst)
         data['CLS'] = '%s.%s' % (cls.__module__, cls.__name__)
         version = getattr(cls, '_version', None)
         if version:
             data['$version'] = version
         if hasattr(cls, '_save'):
             inst._save = self.save
         return 'inst', data
     raise SerializationError(str(cls))
Example #8
0
 def custom(self, name, data):
     storage = self.storage()
     if name == 'ref':
         return Ref(storage, data['path'], data.get('facet'))
     if name == 'inst':
         cls = importSymbol(storage.map_class(data['CLS']))
         data['#vat'] = storage
         data.update(storage.resources)
         # Check for version change.
         data_version = data.get('$version', 0)
         cls_version = getattr(cls, '_version', 0)
         if cls_version != data_version:
             cls._upgrade(data, data_version)
         args = [data.get(key.lstrip('_')) for key in cls.serialize]
         inst = cls(*args)
         if cls_version != data_version:
             # Ensure new nested serializables get correct _save hook.
             encodes(inst, self)
         if hasattr(cls, '_save'):
             inst._save = self.save
         return inst
     raise SerializationError(name)