1

Both json and simplejson support the extension of json.JSONEncoder with the purpose of serializing non-base objects. From the documentation, however, I can't understand how to do this safely.

This is my encoder:

class ReprEncoder(json.JSONEncoder):

    @staticmethod
    def of(*types):
        return ft.partial(ReprEncoder, types)

    def __init__(self, repr_types, **kwargs):
        self.__repr_types = repr_types
        super(ReprEncoder, self).__init__(**kwargs)

    def default(self, obj):
        if type(obj) in self.__repr_types:
            return 'r[%r]' % obj
        return super(ReprEncoder, self).default(obj)

The of methods allows me to provide the classes for which the serialization is supported, and I represent such objects with the convention r[%r]. On deserialization, I plan to use a strategy like if it matches r[ ... ], then deserialize with some (possibly safe!) eval-like technique

With the assumption that, for some class C, C.__repr__ works as expected I can call it as it follows:

c = C('foo', 'bar', 3)
json.dumps(c, cls=ReprEncoder.of(C))

From the documentation it's not clear how to escape strings which are accidentally matching my semantics. The idea would be: if the string to be encoded matches the r[...] syntax, then pre-pend a backslash + On deserialization, look behind r for backslashes.

A trick like:

def default(self, obj):
    # ...
    if type(obj) in types.StringTypes and obj.startswith('r'):
        obj = '\\' + obj
    return super(ReprEncoder, self).default(obj)

Is not going to work, since the default method is called only when the default encoder doesn't have a clue on how to decode data. Also the json.JSONEncode is not implementing things like string (or similar) whilch I could override.

Any hint?

Dacav
  • 13,590
  • 11
  • 60
  • 87

0 Answers0