How to deserialize a string into a dict with json loads with unknown function?

Question:

When I have a string like this

test = '{"key1":"value1", "key2": UnknownFunction("value2")}'

I cannot use json.loads to deserialize its content as the serialized data object contains an unknown function. Is there a simple way to map such a function (or any unknown function) to e.g. str, so that I can deserialize the data object to get a dict like

{"key1":"value1", "key2": "value2"}

?

The following code is working but maybe there is some better way?

for removable in ["UnknownFunction"]:
    test= test.replace(removable + "(", "")
test = test.replace(")", "")
data = json.loads(test)
Asked By: Alex

||

Answers:

You could make use of ast.literal_eval using your own NodeTransformer to handle function calls:

import ast


class Transformer(ast.NodeTransformer):

    def generic_visit(self, node):
        super().generic_visit(node)
        if isinstance(node, ast.Call):
            _args = node.args
            return _args if len(_args) > 0 else ast.Constant(value='null')
        return node


def transform_eval(py_str):
    return ast.literal_eval(Transformer().visit(ast.parse(py_str,
                                                          mode='eval')).body)


testStr = """        {
        "key1": "value1", 
        "key2": UnknownFunction("value1"),
        "key3": foo(),
        }"""

print(transform_eval(testStr.strip()))

Out:

{'key1': 'value1', 'key2': 'value1', 'key3': 'null'}

Note:
I haven’t checked if all possible function argument combinations work: UnknownFunction("value1", foo="bar") or UnknownFunction(*args, foo="bar")

Answered By: Maurice Meyer
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.