def _restore(self, obj):
     if has_tag(obj, tags.ID):
         restore = self._restore_id
     elif has_tag(obj, tags.REF): # Backwards compatibility
         restore = self._restore_ref
     elif has_tag(obj, tags.ITERATOR):
         restore = self._restore_iterator
     elif has_tag(obj, tags.TYPE):
         restore = self._restore_type
     elif has_tag(obj, tags.REPR): # Backwards compatibility
         restore = self._restore_repr
     elif has_tag(obj, tags.REDUCE):
         restore = self._restore_reduce
     elif has_tag(obj, tags.OBJECT):
         restore = self._restore_object
     elif has_tag(obj, tags.FUNCTION):
         restore = self._restore_function
     elif util.is_list(obj):
         restore = self._restore_list
     elif has_tag(obj, tags.TUPLE):
         restore = self._restore_tuple
     elif has_tag(obj, tags.SET):
         restore = self._restore_set
     elif util.is_dictionary(obj):
         restore = self._restore_dict
     else:
         restore = lambda x: x
     return restore(obj)
Esempio n. 2
0
 def _restore(self, obj):
     if has_tag(obj, tags.ID):
         restore = self._restore_id
     elif has_tag(obj, tags.REF):  # Backwards compatibility
         restore = self._restore_ref
     elif has_tag(obj, tags.TYPE):
         restore = self._restore_type
     elif has_tag(obj, tags.REPR):  # Backwards compatibility
         restore = self._restore_repr
     elif has_tag(obj, tags.OBJECT):
         restore = self._restore_object
     elif util.is_list(obj):
         restore = self._restore_list
     elif has_tag(obj, tags.TUPLE):
         restore = self._restore_tuple
     elif has_tag(obj, tags.SET):
         restore = self._restore_set
     elif util.is_dictionary(obj):
         restore = self._restore_dict
     else:
         restore = lambda x: x
     try:
         return restore(obj)
     except IndexError as e:
         raise e  # for testing
Esempio n. 3
0
 def _restore(self, obj):
     if has_tag(obj, tags.B64):
         restore = self._restore_base64
     elif has_tag(obj, tags.BYTES):  # Backwards compatibility
         restore = self._restore_quopri
     elif has_tag(obj, tags.ID):
         restore = self._restore_id
     elif has_tag(obj, tags.REF):  # Backwards compatibility
         restore = self._restore_ref
     elif has_tag(obj, tags.ITERATOR):
         restore = self._restore_iterator
     elif has_tag(obj, tags.TYPE):
         restore = self._restore_type
     elif has_tag(obj, tags.REPR):  # Backwards compatibility
         restore = self._restore_repr
     elif has_tag(obj, tags.REDUCE):
         restore = self._restore_reduce
     elif has_tag(obj, tags.OBJECT):
         restore = self._restore_object
     elif has_tag(obj, tags.FUNCTION):
         restore = self._restore_function
     elif util.is_list(obj):
         restore = self._restore_list
     elif has_tag(obj, tags.TUPLE):
         restore = self._restore_tuple
     elif has_tag(obj, tags.SET):
         restore = self._restore_set
     elif util.is_dictionary(obj):
         restore = self._restore_dict
     else:
         restore = lambda x: x
     return restore(obj)
Esempio n. 4
0
 def _restore(self, obj):
     if has_tag(obj, tags.ID):
         restore = self._restore_id
     elif has_tag(obj, tags.REF): # Backwards compatibility
         restore = self._restore_ref
     elif has_tag(obj, tags.TYPE):
         restore = self._restore_type
     elif has_tag(obj, tags.REPR): # Backwards compatibility
         restore = self._restore_repr
     elif has_tag(obj, tags.OBJECT):
         restore = self._restore_object
     elif util.is_list(obj):
         restore = self._restore_list
     elif has_tag(obj, tags.TUPLE):
         restore = self._restore_tuple
     elif has_tag(obj, tags.SET):
         restore = self._restore_set
     elif util.is_dictionary(obj):
         restore = self._restore_dict
     else:
         restore = lambda x: x
     try:
         return restore(obj)
     except IndexError as e:
         raise e # for testing
Esempio n. 5
0
    def _restore(self, obj, cls=None):
        restore = None

        # Try and restore from an explicit class
        if cls is not None:
            if util.is_type(cls):
                restore = self._restore_object_from_cls
            elif util.is_list(cls):
                restore = self._restore_list_from_cls
            elif util.is_dictionary(cls):
                restore = self._restore_dict_from_cls
            if restore is not None:
                return restore(obj, cls)

        # Try and restore from present tags
        if has_tag(obj, tags.B64):
            restore = self._restore_base64
        elif has_tag(obj, tags.BYTES):  # Backwards compatibility
            restore = self._restore_quopri
        elif has_tag(obj, tags.ID):
            restore = self._restore_id
        elif has_tag(obj, tags.REF):  # Backwards compatibility
            restore = self._restore_ref
        elif has_tag(obj, tags.ITERATOR):
            restore = self._restore_iterator
        elif has_tag(obj, tags.TYPE):
            restore = self._restore_type
        elif has_tag(obj, tags.REPR):  # Backwards compatibility
            restore = self._restore_repr
        elif has_tag(obj, tags.REDUCE):
            restore = self._restore_reduce
        elif has_tag(obj, tags.OBJECT):
            restore = self._restore_object_given_tag
        elif has_tag(obj, tags.FUNCTION):
            restore = self._restore_function
        elif util.is_list(obj):
            restore = self._restore_list_given_tag
        elif has_tag(obj, tags.TUPLE):
            restore = self._restore_tuple
        elif has_tag(obj, tags.SET):
            restore = self._restore_set
        elif util.is_dictionary(obj):
            restore = self._restore_dict_given_tag
        else:
            restore = lambda x: x
        return restore(obj)
Esempio n. 6
0
    def _get_flattener(self, obj):

        if PY2 and isinstance(obj, file):
            return self._flatten_file

        if util.is_primitive(obj):
            return lambda obj: obj

        if util.is_bytes(obj):
            return self._flatten_bytestring

        list_recurse = self._list_recurse

        if util.is_list(obj):
            if self._mkref(obj):
                return list_recurse
            else:
                self._push()
                return self._getref

        # We handle tuples and sets by encoding them in a "(tuple|set)dict"
        if util.is_tuple(obj):
            if not self.unpicklable:
                return list_recurse
            return lambda obj: {tags.TUPLE: [self._flatten(v) for v in obj]}

        if util.is_set(obj):
            if not self.unpicklable:
                return list_recurse
            return lambda obj: {tags.SET: [self._flatten(v) for v in obj]}

        if util.is_dictionary(obj):
            return self._flatten_dict_obj

        if util.is_type(obj):
            return _mktyperef

        if util.is_object(obj):
            return self._ref_obj_instance

        if util.is_module_function(obj):
            return self._flatten_function

        # instance methods, lambdas, old style classes...
        self._pickle_warning(obj)
        return None
Esempio n. 7
0
    def _get_flattener(self, obj):

        if PY2 and isinstance(obj, file):
            return self._flatten_file

        if util.is_primitive(obj):
            return lambda obj: obj

        if util.is_bytes(obj):
            return self._flatten_bytestring

        list_recurse = self._list_recurse

        if util.is_list(obj):
            if self._mkref(obj):
                return list_recurse
            else:
                self._push()
                return self._getref

        # We handle tuples and sets by encoding them in a "(tuple|set)dict"
        if util.is_tuple(obj):
            if not self.unpicklable:
                return list_recurse
            return lambda obj: {tags.TUPLE: [self._flatten(v) for v in obj]}

        if util.is_set(obj):
            if not self.unpicklable:
                return list_recurse
            return lambda obj: {tags.SET: [self._flatten(v) for v in obj]}

        if util.is_dictionary(obj):
            return self._flatten_dict_obj

        if util.is_type(obj):
            return _mktyperef

        if util.is_object(obj):
            return self._ref_obj_instance

        if util.is_module_function(obj):
            return self._flatten_function

        # instance methods, lambdas, old style classes...
        self._pickle_warning(obj)
        return None
Esempio n. 8
0
    def _get_flattener(self, obj):

        if util.is_primitive(obj):
            return lambda obj: obj

        list_recurse = self._list_recurse

        if util.is_list(obj):
            if self._mkref(obj):
                return list_recurse
            else:
                self._push()
                return self._getref

        # We handle tuples and sets by encoding them in a "(tuple|set)dict"
        if util.is_tuple(obj):
            if not self.unpicklable:
                return list_recurse
            return lambda obj: {tags.TUPLE: [self._flatten(v) for v in obj]}

        if util.is_set(obj):
            if not self.unpicklable:
                return list_recurse
            return lambda obj: {tags.SET: [self._flatten(v) for v in obj]}

        if util.is_dictionary(obj):
            return self._flatten_dict_obj

        if util.is_type(obj):
            return _mktyperef

        if util.is_object(obj):
            return self._ref_obj_instance

        # else, what else? (methods, functions, old style classes...)
        return None
Esempio n. 9
0
    def _get_flattener(self, obj):

        if util.is_primitive(obj):
            return lambda obj: obj

        list_recurse = self._list_recurse

        if util.is_list(obj):
            if self._mkref(obj):
                return list_recurse
            else:
                self._push()
                return self._getref

        # We handle tuples and sets by encoding them in a "(tuple|set)dict"
        if util.is_tuple(obj):
            if not self.unpicklable:
                return list_recurse
            return lambda obj: {tags.TUPLE: [self._flatten(v) for v in obj]}

        if util.is_set(obj):
            if not self.unpicklable:
                return list_recurse
            return lambda obj: {tags.SET: [self._flatten(v) for v in obj]}

        if util.is_dictionary(obj):
            return self._flatten_dict_obj

        if util.is_type(obj):
            return _mktyperef

        if util.is_object(obj):
            return self._ref_obj_instance

        # else, what else? (methods, functions, old style classes...)
        return None
Esempio n. 10
0
 def test_is_list_other(self):
     self.assertFalse(is_list(1))
     self.assertFalse(is_set(1))
     self.assertFalse(is_tuple(1))
Esempio n. 11
0
 def test_is_list_dict(self):
     self.assertFalse(is_list({'key':'value'}))
     self.assertFalse(is_set({'key':'value'}))
     self.assertFalse(is_tuple({'key':'value'}))
Esempio n. 12
0
 def test_is_list_list(self):
     self.assertTrue(is_list([1, 2]))
Esempio n. 13
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,2,))[tags.TUPLE]
        [1, 2]
        >>> p.flatten({'key': 'value'})
        {'key': 'value'}
        """

        self._push()

        if self._depth == self._max_depth:
            return self._pop(repr(obj))

        if util.is_primitive(obj):
            return self._pop(obj)

        if util.is_list(obj):
            return self._pop([self.flatten(v) for v in obj])

        # We handle tuples and sets by encoding them in a "(tuple|set)dict"
        if util.is_tuple(obj):
            return self._pop({tags.TUPLE: [self.flatten(v) for v in obj]})

        if util.is_set(obj):
            return self._pop({tags.SET: [self.flatten(v) for v in obj]})

        if util.is_dictionary(obj):
            return self._pop(self._flatten_dict_obj(obj, obj.__class__()))

        if util.is_type(obj):
            return self._pop(_mktyperef(obj))

        if util.is_object(obj):
            data = {}
            has_class = hasattr(obj, '__class__')
            has_dict = hasattr(obj, '__dict__')
            if self._mkref(obj):
                if has_class and not util.is_repr(obj):
                    module, name = _getclassdetail(obj)
                    if self.unpicklable is True:
                        data[tags.OBJECT] = '%s.%s' % (module, name)

                if util.is_repr(obj):
                    if self.unpicklable is True:
                        data[tags.REPR] = '%s/%s' % (obj.__class__.__module__,
                                                     repr(obj))
                    else:
                        data = unicode(obj)
                    return self._pop(data)

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

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

                if has_dict:
                    return self._pop(self._flatten_dict_obj(
                        obj.__dict__, data))
            else:
                # We've seen this object before so place an object
                # reference tag in the data. This avoids infinite recursion
                # when processing cyclical objects.
                return self._pop(self._getref(obj))

            return self._pop(data)
Esempio n. 14
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'}
        """
        self._push()

        if has_tag(obj, tags.REF):
            return self._pop(self._namedict.get(obj[tags.REF]))

        if has_tag(obj, tags.TYPE):
            typeref = loadclass(obj[tags.TYPE])
            if not typeref:
                return self._pop(obj)
            return self._pop(typeref)

        if has_tag(obj, tags.REPR):
            return self._pop(loadrepr(obj[tags.REPR]))

        if has_tag(obj, tags.OBJECT):

            cls = loadclass(obj[tags.OBJECT])
            if not cls:
                return self._pop(obj)
            try:
                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)

            for k, v in obj.iteritems():
                # 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:
                    instance.__dict__[k] = value
                # step out
                self._namestack.pop()
            return self._pop(instance)

        if util.is_list(obj):
            return self._pop([self.restore(v) for v in obj])

        if has_tag(obj, tags.TUPLE):
            return self._pop(tuple([self.restore(v) for v in obj[tags.TUPLE]]))

        if has_tag(obj, tags.SET):
            return self._pop(set([self.restore(v) for v in obj[tags.SET]]))

        if util.is_dictionary(obj):
            data = {}
            for k, v in obj.iteritems():
                self._namestack.append(k)
                data[k] = self.restore(v)
                self._namestack.pop()
            return self._pop(data)

        return self._pop(obj)
Esempio n. 15
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'}
        """
        self._push()

        if has_tag(obj, tags.ID):
            return self._pop(self._objs[obj[tags.ID]])

        # Backwards compatibility
        if has_tag(obj, tags.REF):
            return self._pop(self._namedict.get(obj[tags.REF]))

        if has_tag(obj, tags.TYPE):
            typeref = loadclass(obj[tags.TYPE])
            if not typeref:
                return self._pop(obj)
            return self._pop(typeref)

        # Backwards compatibility
        if has_tag(obj, tags.REPR):
            obj = loadrepr(obj[tags.REPR])
            return self._pop(self._mkref(obj))

        if has_tag(obj, tags.OBJECT):
            cls = loadclass(obj[tags.OBJECT])
            if not cls:
                return self._pop(self._mkref(obj))

            # check custom handlers
            HandlerClass = handlers.registry.get(cls)
            if HandlerClass:
                handler = HandlerClass(self)
                instance = handler.restore(obj)
                return self._pop(self._mkref(instance))

            factory = loadfactory(obj)
            args = getargs(obj)
            if args:
                args = self.restore(args)
            try:
                if hasattr(cls, '__new__'):
                    # new style classes
                    if factory:
                        instance = cls.__new__(cls, factory, *args)
                        instance.default_factory = factory
                    else:
                        instance = cls.__new__(cls, *args)
                else:
                    instance = object.__new__(cls)
            except TypeError:
                # old-style classes
                try:
                    instance = cls()
                except TypeError:
                    # fail gracefully if the constructor requires arguments
                    return self._pop(self._mkref(obj))

            # Add to the instance table to allow being referenced by a
            # downstream object
            self._mkref(instance)

            if hasattr(instance, '__setstate__') and has_tag(obj, tags.STATE):
                state = self.restore(obj[tags.STATE])
                instance.__setstate__(state)
                return self._pop(instance)

            for k, v in sorted(obj.items(), key=operator.itemgetter(0)):
                # 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))

            return self._pop(instance)

        if util.is_list(obj):
            parent = []
            self._mkref(parent)
            children = [self.restore(v) for v in obj]
            parent.extend(children)
            return self._pop(parent)

        if has_tag(obj, tags.TUPLE):
            return self._pop(tuple([self.restore(v)
                                    for v in obj[tags.TUPLE]]))

        if has_tag(obj, tags.SET):
            return self._pop(set([self.restore(v)
                                  for v in obj[tags.SET]]))

        if util.is_dictionary(obj):
            data = {}
            for k, v in sorted(obj.items(), key=operator.itemgetter(0)):
                self._namestack.append(k)
                data[k] = self.restore(v)
                self._namestack.pop()

            return self._pop(data)

        return self._pop(obj)
Esempio n. 16
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'}
        """
        self._push()

        if has_tag(obj, tags.ID):
            return self._pop(self._objs[obj[tags.ID]])

        if has_tag(obj, tags.REF):
            return self._pop(self._namedict.get(obj[tags.REF]))

        if has_tag(obj, tags.TYPE):
            typeref = loadclass(obj[tags.TYPE])
            if not typeref:
                return self._pop(obj)
            return self._pop(typeref)

        if has_tag(obj, tags.REPR):
            return self._pop(loadrepr(obj[tags.REPR]))

        if has_tag(obj, tags.OBJECT):

            cls = loadclass(obj[tags.OBJECT])
            if not cls:
                return self._pop(obj)

            # check custom handlers
            HandlerClass = handlers.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, tags.STATE):
                state = self.restore(obj[tags.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 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))

            return self._pop(instance)

        if util.is_list(obj):
            return self._pop([self.restore(v) for v in obj])

        if has_tag(obj, tags.TUPLE):
            return self._pop(tuple([self.restore(v) for v in obj[tags.TUPLE]]))

        if has_tag(obj, tags.SET):
            return self._pop(set([self.restore(v) for v in obj[tags.SET]]))

        if util.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)

        return self._pop(obj)
Esempio n. 17
0
 def test_is_list_other(self):
     self.assertFalse(util.is_list(1))
     self.assertFalse(util.is_set(1))
     self.assertFalse(util.is_tuple(1))
Esempio n. 18
0
 def test_is_list_dict(self):
     self.assertFalse(util.is_list({'key': 'value'}))
     self.assertFalse(util.is_set({'key': 'value'}))
     self.assertFalse(util.is_tuple({'key': 'value'}))
Esempio n. 19
0
 def test_is_list_list(self):
     self.assertTrue(util.is_list([1, 2]))
Esempio n. 20
0
 def test_is_list_dict(self):
     self.assertFalse(is_list({"key": "value"}))
     self.assertFalse(is_set({"key": "value"}))
     self.assertFalse(is_tuple({"key": "value"}))
Esempio n. 21
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,2,))[tags.TUPLE]
        [1, 2]
        >>> p.flatten({'key': 'value'})
        {'key': 'value'}
        """
        self._push()

        if self._depth == self._max_depth:
            return self._pop(repr(obj))

        if util.is_primitive(obj):
            return self._pop(obj)

        if util.is_list(obj):
            if self._mkref(obj):
                return self._pop([self.flatten(v) for v in obj])
            else:
                return self._getref(obj)

        # We handle tuples and sets by encoding them in a "(tuple|set)dict"
        if util.is_tuple(obj):
            if self.unpicklable:
                return self._pop({tags.TUPLE: [self.flatten(v) for v in obj]})
            else:
                return self._pop([self.flatten(v) for v in obj])

        if util.is_set(obj):
            if self.unpicklable:
                return self._pop({tags.SET: [self.flatten(v) for v in obj]})
            else:
                return self._pop([self.flatten(v) for v in obj])

        if util.is_dictionary(obj):
            return self._pop(self._flatten_dict_obj(obj, obj.__class__()))

        if util.is_type(obj):
            return self._pop(_mktyperef(obj))

        if util.is_object(obj):
            if self._mkref(obj):
                # We've never seen this object so return its
                # json representation.
                return self._pop(self._flatten_obj_instance(obj))
            else:
                # We've seen this object before so place an object
                # reference tag in the data. This avoids infinite recursion
                # when processing cyclical objects.
                return self._pop(self._getref(obj))
        # else, what else? (methods, functions, old style classes...)
        return None
Esempio n. 22
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,2,))[tags.TUPLE]
        [1, 2]
        >>> p.flatten({'key': 'value'})
        {'key': 'value'}
        """

        self._push()
        
        if self._depth == self._max_depth:
            return self._pop(repr(obj))

        if util.is_primitive(obj):
            return self._pop(obj)

        if util.is_list(obj):
            return self._pop([ self.flatten(v) for v in obj ])

        # We handle tuples and sets by encoding them in a "(tuple|set)dict"
        if util.is_tuple(obj):
            return self._pop({tags.TUPLE: [ self.flatten(v) for v in obj ]})

        if util.is_set(obj):
            return self._pop({tags.SET: [ self.flatten(v) for v in obj ]})

        if util.is_dictionary(obj):
            return self._pop(self._flatten_dict_obj(obj, obj.__class__()))

        if util.is_type(obj):
            return self._pop(_mktyperef(obj))

        if util.is_object(obj):
            data = {}
            has_class = hasattr(obj, '__class__')
            has_dict = hasattr(obj, '__dict__')
            if self._mkref(obj):
                if has_class and not util.is_repr(obj):
                    module, name = _getclassdetail(obj)
                    if self.unpicklable is True:
                        data[tags.OBJECT] = '%s.%s' % (module, name)

                if util.is_repr(obj):
                    if self.unpicklable is True:
                        data[tags.REPR] = '%s/%s' % (obj.__class__.__module__,
                                                     repr(obj))
                    else:
                        data = unicode(obj)
                    return self._pop(data)

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

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

                if has_dict:
                    return self._pop(self._flatten_dict_obj(obj.__dict__, data))
            else:
                # We've seen this object before so place an object
                # reference tag in the data. This avoids infinite recursion
                # when processing cyclical objects.
                return self._pop(self._getref(obj))

            return self._pop(data)
Esempio n. 23
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'}
        """
        self._push()

        if has_tag(obj, tags.REF):
            return self._pop(self._namedict.get(obj[tags.REF]))

        if has_tag(obj, tags.TYPE):
            typeref = loadclass(obj[tags.TYPE])
            if not typeref:
                return self._pop(obj)
            return self._pop(typeref)

        if has_tag(obj, tags.REPR):
            return self._pop(loadrepr(obj[tags.REPR]))

        if has_tag(obj, tags.OBJECT):

            cls = loadclass(obj[tags.OBJECT])
            if not cls:
                return self._pop(obj)
            try:
                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)

            for k, v in obj.iteritems():
                # 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:
                    instance.__dict__[k] = value
                # step out
                self._namestack.pop()
            return self._pop(instance)

        if util.is_list(obj):
            return self._pop([self.restore(v) for v in obj])

        if has_tag(obj, tags.TUPLE):
            return self._pop(tuple([self.restore(v) for v in obj[tags.TUPLE]]))

        if has_tag(obj, tags.SET):
            return self._pop(set([self.restore(v) for v in obj[tags.SET]]))

        if util.is_dictionary(obj):
            data = {}
            for k, v in obj.iteritems():
                self._namestack.append(k)
                data[k] = self.restore(v)
                self._namestack.pop()
            return self._pop(data)

        return self._pop(obj)
Esempio n. 24
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,2,))[tags.TUPLE]
        [1, 2]
        >>> p.flatten({'key': 'value'})
        {'key': 'value'}
        """

        self._push()

        if self._depth == self._max_depth:
            return self._pop(repr(obj))

        if util.is_primitive(obj):
            return self._pop(obj)

        if util.is_list(obj):
            return self._pop([ self.flatten(v) for v in obj ])

        # We handle tuples and sets by encoding them in a "(tuple|set)dict"
        if util.is_tuple(obj):
            return self._pop({tags.TUPLE: [ self.flatten(v) for v in obj ]})

        if util.is_set(obj):
            return self._pop({tags.SET: [ self.flatten(v) for v in obj ]})

        if util.is_dictionary(obj):
            return self._pop(self._flatten_dict_obj(obj, obj.__class__()))

        if util.is_type(obj):
            return self._pop(_mktyperef(obj))

        if util.is_object(obj):
            if self._mkref(obj):
                # We've never seen this object so return its
                # json representation.
                return self._pop(self._flatten_obj_instance(obj))
            else:
                # We've seen this object before so place an object
                # reference tag in the data. This avoids infinite recursion
                # when processing cyclical objects.
                return self._pop(self._getref(obj))

            return self._pop(data)
Esempio n. 25
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'}
        """
        self._push()

        if has_tag(obj, tags.ID):
            return self._pop(self._objs[obj[tags.ID]])

        # Backwards compatibility
        if has_tag(obj, tags.REF):
            return self._pop(self._namedict.get(obj[tags.REF]))

        if has_tag(obj, tags.TYPE):
            typeref = loadclass(obj[tags.TYPE])
            if not typeref:
                return self._pop(obj)
            return self._pop(typeref)

        # Backwards compatibility
        if has_tag(obj, tags.REPR):
            obj = loadrepr(obj[tags.REPR])
            return self._pop(self._mkref(obj))

        if has_tag(obj, tags.OBJECT):
            cls = loadclass(obj[tags.OBJECT])
            if not cls:
                return self._pop(self._mkref(obj))

            # check custom handlers
            HandlerClass = handlers.BaseHandler._registry.get(cls)
            if HandlerClass:
                handler = HandlerClass(self)
                instance = handler.restore(obj)
                return self._pop(self._mkref(instance))

            factory = loadfactory(obj)
            args = getargs(obj)
            if args:
                args = self.restore(args)
            try:
                if hasattr(cls, '__new__'):
                    # new style classes
                    if factory:
                        instance = cls.__new__(cls, factory, *args)
                        instance.default_factory = factory
                    else:
                        instance = cls.__new__(cls, *args)
                else:
                    instance = object.__new__(cls)
            except TypeError:
                # old-style classes
                try:
                    instance = cls()
                except TypeError:
                    # fail gracefully if the constructor requires arguments
                    return self._pop(self._mkref(obj))

            # Add to the instance table to allow being referenced by a
            # downstream object
            self._mkref(instance)

            if isinstance(instance, tuple):
                return self._pop(instance)

            if hasattr(instance, '__setstate__') and has_tag(obj, tags.STATE):
                state = self.restore(obj[tags.STATE])
                instance.__setstate__(state)
                return self._pop(instance)

            for k, v in sorted(obj.items(), key=operator.itemgetter(0)):
                # 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))

            return self._pop(instance)

        if util.is_list(obj):
            parent = []
            self._mkref(parent)
            children = [self.restore(v) for v in obj]
            parent.extend(children)
            return self._pop(parent)

        if has_tag(obj, tags.TUPLE):
            return self._pop(tuple([self.restore(v) for v in obj[tags.TUPLE]]))

        if has_tag(obj, tags.SET):
            return self._pop(set([self.restore(v) for v in obj[tags.SET]]))

        if util.is_dictionary(obj):
            data = {}
            for k, v in sorted(obj.items(), key=operator.itemgetter(0)):
                self._namestack.append(k)
                data[k] = self.restore(v)
                self._namestack.pop()

            return self._pop(data)

        return self._pop(obj)