xlwings / jsondiff

Diff JSON and JSON-like structures in Python
MIT License
688 stars 87 forks source link

Cant use standard json.dump #19

Open lexapi opened 6 years ago

lexapi commented 6 years ago

Example:

a = {
    "dict": {
        "nested_list": [
            {
                "@dict_list_dict_f1": 1,
            },
            {
                "@dict_list_dict_f1": 2,
            },
        ]
    }
}

b = {
    "dict": {
        "nested_list": [
            {
                "@dict_list_dict_f1": 1,
            },
        ]
    }
}

from jsondiff import diff
d=diff(a, b, syntax='symmetric')

print(diff)
{'dict': {'nested_list': {delete: [(1, {'@dict_list_dict_f1': 2})]}}}

print(json.dumps(diff))

Traceback (most recent call last):
    print(json.dumps(diff))
  File "/usr/lib/python3.5/json/__init__.py", line 230, in dumps
    return _default_encoder.encode(obj)
  File "/usr/lib/python3.5/json/encoder.py", line 198, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python3.5/json/encoder.py", line 256, in iterencode
    return _iterencode(o, 0)
TypeError: keys must be a string

print(diff(a, b,  syntax='symmetric', dump=True))
{"dict": {"nested_list": {"$delete": [[1, {"@dict_list_dict_f1": 2}]]}}}
# internal dump convert nested tuple to list ???
fedorov commented 5 years ago

I think I had a similar issue. I fixed it by passing marshal=True to diff.

larsks commented 5 years ago

I came here to report the same problem; I wonder if marshal=True should be the default behavior? It seems surprising that the output of jsondiff.diff is not itself JSON serializable.

richard-jones commented 5 years ago

I also came here for the same reason. I ended up implementing a hacky parser which switches the Symbols for strings, wish I'd know about marshal=True.

The problem with having the insert and delete keywords as strings is that you can't tell them apart from a data structure with insert and delete as legitimate keys, so I can see the reasoning for making them symbols.

Perhaps a better longer term solution would be to adopt the output semantics of JSONPatch, which is completely unambigous, and is native JSON: http://jsonpatch.com/