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'} """ self._push() if has_tag(obj, REF): return self._pop(self._namedict.get(obj[REF])) if has_tag(obj, TYPE): typeref = loadclass(obj[TYPE]) if not typeref: return self._pop(obj) return self._pop(typeref) if has_tag(obj, REPR): return self._pop(loadrepr(obj[REPR])) if has_tag(obj, OBJECT): cls = loadclass(obj[OBJECT]) if not cls: return self._pop(obj) # check custom handlers HandlerClass = registry.get(cls) if HandlerClass: handler = HandlerClass(self) return self._pop(handler.restore(obj)) try: if hasattr(cls, '__new__'): instance = cls.__new__(cls) else: instance = object.__new__(cls) except TypeError: # old-style classes try: instance = cls() except TypeError: # fail gracefully if the constructor requires arguments self._mkref(obj) return self._pop(obj) # keep a obj->name mapping for use in the _isobjref() case self._mkref(instance) if hasattr(instance, '__setstate__') and has_tag(obj, STATE): state = self.restore(obj[STATE]) instance.__setstate__(state) return self._pop(instance) for k, v in sorted(obj.iteritems(), key=operator.itemgetter(0)): # ignore the reserved attribute if k in RESERVED: continue self._namestack.append(k) # step into the namespace value = self.restore(v) if (is_noncomplex(instance) or 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, SEQ): if hasattr(instance, 'append'): for v in obj[SEQ]: instance.append(self.restore(v)) if hasattr(instance, 'add'): for v in obj[SEQ]: instance.add(self.restore(v)) return self._pop(instance) if is_list(obj): return self._pop([self.restore(v) for v in obj]) if has_tag(obj, TUPLE): return self._pop(tuple([self.restore(v) for v in obj[TUPLE]])) if has_tag(obj, SET): return self._pop(set([self.restore(v) for v in obj[SET]])) if is_dictionary(obj): data = {} for k, v in sorted(obj.iteritems(), key=operator.itemgetter(0)): self._namestack.append(k) data[k] = self.restore(v) self._namestack.pop() return self._pop(data) if is_date(obj): from datetime import datetime unix_time = int(DATE_REG_EXP.findall(obj)[0]) / 1000 #since js getTime is in ms return self._pop(datetime.fromtimestamp(unix_time)) return self._pop(obj)
"""The jsonpickle.tags module provides the custom tags used for pickling and unpickling Python objects. These tags are keys into the flattened dictionaries created by the Pickler class. The Unpickler uses these custom key names to identify dictionaries that need to be specially handled. """ import re from tic.utils.jsonpickle.compat import set DATE_REG_EXP = re.compile("^new Date\((?P<unix_time>\d+)\)$") OBJECT = 'declaredClass' # customizes to match the dojo specs TYPE = 'py/type' REPR = 'py/repr' REF = 'py/ref' TUPLE = 'py/tuple' SET = 'py/set' SEQ = 'py/seq' STATE = 'py/state' # All reserved tag names RESERVED = set([OBJECT, TYPE, REPR, REF, TUPLE, SET, SEQ, STATE])