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
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)
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
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
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