示例#1
0
    def _restore_object_instance_variables(self, obj, instance):
        for k, v in sorted(obj.items(), key=util.itemgetter):
            # ignore the reserved attribute
            if k in tags.RESERVED:
                continue
            self._namestack.append(k)
            # step into the namespace
            value = self._restore(v)
            if (util.is_noncomplex(instance) or
                    util.is_dictionary_subclass(instance)):
                instance[k] = value
            else:
                setattr(instance, k, value)
            # step out
            self._namestack.pop()

        # Handle list and set subclasses
        if has_tag(obj, tags.SEQ):
            if hasattr(instance, 'append'):
                for v in obj[tags.SEQ]:
                    instance.append(self._restore(v))
            if hasattr(instance, 'add'):
                for v in obj[tags.SEQ]:
                    instance.add(self._restore(v))

        if _supports_getstate(obj, instance):
            self._restore_state(obj, instance)

        return instance
示例#2
0
    def _restore_object_instance_variables(self, obj, instance):
        for k, v in sorted(obj.items(), key=util.itemgetter):
            # ignore the reserved attribute
            if k in tags.RESERVED:
                continue
            self._namestack.append(k)
            # step into the namespace
            value = self._restore(v)
            if (util.is_noncomplex(instance)
                    or util.is_dictionary_subclass(instance)):
                instance[k] = value
            else:
                setattr(instance, k, value)
            # step out
            self._namestack.pop()

        # Handle list and set subclasses
        if has_tag(obj, tags.SEQ):
            if hasattr(instance, 'append'):
                for v in obj[tags.SEQ]:
                    instance.append(self._restore(v))
            if hasattr(instance, 'add'):
                for v in obj[tags.SEQ]:
                    instance.add(self._restore(v))

        if _supports_getstate(obj, instance):
            self._restore_state(obj, instance)

        return instance
示例#3
0
    def _flatten_obj_instance(self, obj):
        """Recursively flatten an instance and return a json-friendly dict
        """
        data = {}
        has_class = hasattr(obj, '__class__')
        has_dict = hasattr(obj, '__dict__')
        has_slots = not has_dict and hasattr(obj, '__slots__')

        # Support objects with __getstate__(); this ensures that
        # both __setstate__() and __getstate__() are implemented
        has_getstate = hasattr(obj, '__getstate__')
        has_getstate_support = has_getstate and hasattr(obj, '__setstate__')

        if has_class and not util.is_module(obj):
            module, name = _getclassdetail(obj)
            if self.unpicklable:
                #ksteinfe
                if module[:12] == "decodes.core": data[tags.OBJECT] = name
                else: data[tags.OBJECT] = '%s.%s' % (module, name)
            # Check for a custom handler
            handler = handlers.get(type(obj))
            if handler is not None:
                return handler(self).flatten(obj, data)

        if util.is_module(obj):
            if self.unpicklable:
                data[tags.REPR] = '%s/%s' % (obj.__name__,
                                             obj.__name__)
            else:
                data = unicode(obj)
            return data

        if util.is_dictionary_subclass(obj):
            self._flatten_dict_obj(obj, data)
            if has_getstate_support:
                self._getstate(obj, data)
            return data

        if has_dict:
            # Support objects that subclasses list and set
            if util.is_sequence_subclass(obj):
                return self._flatten_sequence_obj(obj, data)

            if has_getstate_support:
                return self._getstate(obj, data)

            # hack for zope persistent objects; this unghostifies the object
            getattr(obj, '_', None)
            return self._flatten_dict_obj(obj.__dict__, data)

        if util.is_sequence_subclass(obj):
            return self._flatten_sequence_obj(obj, data)

        if util.is_noncomplex(obj):
            return [self._flatten(v) for v in obj]

        if has_slots:
            return self._flatten_newstyle_with_slots(obj, data)
示例#4
0
 def restore(self, obj):
     """Restores a flattened object to its original python state.
     
     Simply returns any of the basic builtin types
     >>> u = Unpickler()
     >>> u.restore('hello world')
     'hello world'
     >>> u.restore({'key': 'value'})
     {'key': 'value'}
     """
     if self._isclassdict(obj):
         cls = self._loadclass(obj['classmodule__'], obj['classname__'])
         
         try:
             instance = object.__new__(cls)
         except TypeError:
             # old-style classes
             instance = cls()
         
         for k, v in obj.iteritems():
             # ignore the fake attribute
             if k in ['classmodule__', 'classname__']:
                 continue
             if k == 'classdictitems__':
                 for dictk, dictv in v.iteritems():
                     instance[dictk] = self.restore(dictv)
                 continue
             value = self.restore(v)
             if util.is_noncomplex(instance):
                 instance[k] = value
             else:
                 instance.__dict__[k] = value
         return instance
     elif util.iscollection(obj):
         # currently restores all collections to lists, even sets and tuples
         data = []
         for v in obj:
             data.append(self.restore(v))
         return data
     elif util.isdictionary(obj):
         data = {}
         for k, v in obj.iteritems():
             data[k] = self.restore(v)
         return data
     else:
         return obj
示例#5
0
 def restore(self, obj):
     """Restores a flattened object to its original python state.
     
     Simply returns any of the basic builtin types
     >>> u = Unpickler()
     >>> u.restore('hello world')
     'hello world'
     >>> u.restore({'key': 'value'})
     {'key': 'value'}
     """
     if self._isclassdict(obj):
         cls = self._loadclass(obj['classmodule__'], obj['classname__'])
         
         try:
             instance = object.__new__(cls)
         except TypeError:
             # old-style classes
             instance = cls()
         
         for k, v in obj.iteritems():
             # ignore the fake attribute
             if k in ['classmodule__', 'classname__']:
                 continue
             if k == 'classdictitems__':
                 for dictk, dictv in v.iteritems():
                     instance[dictk] = self.restore(dictv)
                 continue
             value = self.restore(v)
             if util.is_noncomplex(instance):
                 instance[k] = value
             else:
                 instance.__dict__[k] = value
         return instance
     elif util.iscollection(obj):
         # currently restores all collections to lists, even sets and tuples
         data = []
         for v in obj:
             data.append(self.restore(v))
         return data
     elif util.isdictionary(obj):
         data = {}
         for k, v in obj.iteritems():
             data[k] = self.restore(v)
         return data
     else:
         return obj
示例#6
0
 def flatten(self, obj):
     """Takes an object and returns a JSON-safe representation of it.
     
     Simply returns any of the basic builtin datatypes
     >>> p = Pickler()
     >>> p.flatten('hello world')
     'hello world'
     >>> p.flatten(u'hello world')
     u'hello world'
     >>> p.flatten(49)
     49
     >>> p.flatten(350.0)
     350.0
     >>> p.flatten(True)
     True
     >>> p.flatten(False)
     False
     >>> r = p.flatten(None)
     >>> r is None
     True
     >>> p.flatten(False)
     False
     >>> p.flatten([1, 2, 3, 4])
     [1, 2, 3, 4]
     >>> p.flatten((1,))
     (1,)
     >>> p.flatten({'key': 'value'})
     {'key': 'value'}
     """
     
     if util.isprimitive(obj):
         #logging.info('Returning: %s', obj)
         return obj
     elif util.iscollection(obj):
         data = [] # obj.__class__()
         for v in obj:
             data.append(self.flatten(v))
         return obj.__class__(data)
         #TODO handle tuple and sets
     elif util.isdictionary(obj):
         data = obj.__class__()
         for k, v in obj.iteritems():
             data[k] = self.flatten(v)
         return data
     elif isinstance(obj, object):
         #logging.info('Type: %s', type(obj))
         data = {}
         #module, name = self._getclassdetail(obj)
         #if self.unpicklable is True:
         #    data['classmodule__'] = module
         #    data['classname__'] = name 
         if util.is_dictionary_subclass(obj):
             if self.unpicklable is True:
                 # this will place items in a sub dictionary (arguably not a pure JSON representation, 
                 # since it should be at root level.  However, this method preserves the object
                 # so that it can be recreated as a Python object
                 data['classdictitems__'] = self.flatten(dict(obj))
             else:
                 # this option will place everything at root, but it allows a dictionary key
                 # to overwrite an instance variable if both have the same name
                 for k, v in obj.iteritems():
                     data[k] = self.flatten(v)
         #elif util.is_collection_subclass(obj):
         #    data['__classcollectionitems__'] = self.flatten()
         elif util.is_noncomplex(obj):
             data = [] # obj.__class__()
             for v in obj:
                 data.append(self.flatten(v))
         #elif obj.__getattribute__('__dict__') is not None:
         else:
             try:
                 for k, v in obj.__dict__.iteritems():
                     #logging.info('Flattening k,v: %s,%s', k, v)
                     data[str(k)] = self.flatten(v)
             except AttributeError:
                 return data
         return data
示例#7
0
 def flatten(self, obj):
     """Takes an object and returns a JSON-safe representation of it.
     
     Simply returns any of the basic builtin datatypes
     >>> p = Pickler()
     >>> p.flatten('hello world')
     'hello world'
     >>> p.flatten(u'hello world')
     u'hello world'
     >>> p.flatten(49)
     49
     >>> p.flatten(350.0)
     350.0
     >>> p.flatten(True)
     True
     >>> p.flatten(False)
     False
     >>> r = p.flatten(None)
     >>> r is None
     True
     >>> p.flatten(False)
     False
     >>> p.flatten([1, 2, 3, 4])
     [1, 2, 3, 4]
     >>> p.flatten((1,))
     (1,)
     >>> p.flatten({'key': 'value'})
     {'key': 'value'}
     """
     
     if util.isprimitive(obj):
         return obj
     elif util.iscollection(obj):
         data = [] # obj.__class__()
         for v in obj:
             data.append(self.flatten(v))
         return obj.__class__(data)
         #TODO handle tuple and sets
     elif util.isdictionary(obj):
         data = obj.__class__()
         for k, v in obj.iteritems():
             data[k] = self.flatten(v)
         return data
     elif isinstance(obj, object):
         data = {}
         module, name = self._getclassdetail(obj)
         if self.unpicklable is True:
             data['classmodule__'] = module
             data['classname__'] = name 
         if util.is_dictionary_subclass(obj):
             if self.unpicklable is True:
                 # this will place items in a sub dictionary (arguably not a pure JSON representation, 
                 # since it should be at root level.  However, this method preserves the object
                 # so that it can be recreated as a Python object
                 data['classdictitems__'] = self.flatten(dict(obj))
             else:
                 # this option will place everything at root, but it allows a dictionary key
                 # to overwrite an instance variable if both have the same name
                 for k, v in obj.iteritems():
                     data[k] = self.flatten(v)
         #elif util.is_collection_subclass(obj):
         #    data['__classcollectionitems__'] = self.flatten()
         elif util.is_noncomplex(obj):
             data = [] # obj.__class__()
             for v in obj:
                 data.append(self.flatten(v))
         else:
             for k, v in obj.__dict__.iteritems():
                 data[str(k)] = self.flatten(v)
         return data