Skip to content

Commit

Permalink
fixes to_json() method chokes on some standard json.dumps() such as
Browse files Browse the repository at this point in the history
sort_keys #490
  • Loading branch information
seperman committed Dec 15, 2024
1 parent f1d87e9 commit 42fd42d
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 4 deletions.
30 changes: 26 additions & 4 deletions deepdiff/serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ def from_json_pickle(cls, value):
else:
logger.error('jsonpickle library needs to be installed in order to run from_json_pickle') # pragma: no cover. Json pickle is getting deprecated.

def to_json(self, default_mapping=None, **kwargs):
def to_json(self, default_mapping: dict | None=None, force_use_builtin_json=False, **kwargs):
"""
Dump json of the text view.
**Parameters**
Expand All @@ -190,6 +190,11 @@ def to_json(self, default_mapping=None, **kwargs):
If you have a certain object type that the json serializer can not serialize it, please pass the appropriate type
conversion through this dictionary.
force_use_builtin_json: Boolean, default = False
When True, we use Python's builtin Json library for serialization,
even if Orjson is installed.
kwargs: Any other kwargs you pass will be passed on to Python's json.dumps()
**Example**
Expand All @@ -212,7 +217,12 @@ def to_json(self, default_mapping=None, **kwargs):
'{"type_changes": {"root": {"old_type": "A", "new_type": "B", "old_value": "obj A", "new_value": "obj B"}}}'
"""
dic = self.to_dict(view_override=TEXT_VIEW)
return json_dumps(dic, default_mapping=default_mapping, **kwargs)
return json_dumps(
dic,
default_mapping=default_mapping,
force_use_builtin_json=force_use_builtin_json,
**kwargs,
)

def to_dict(self, view_override=None):
"""
Expand Down Expand Up @@ -637,14 +647,26 @@ def object_hook(self, obj):
return obj


def json_dumps(item, default_mapping=None, **kwargs):
def json_dumps(item, default_mapping=None, force_use_builtin_json: bool=False, **kwargs):
"""
Dump json with extra details that are not normally json serializable
parameters
----------
force_use_builtin_json: Boolean, default = False
When True, we use Python's builtin Json library for serialization,
even if Orjson is installed.
"""
if orjson:
if orjson and not force_use_builtin_json:
indent = kwargs.pop('indent', None)
if indent:
kwargs['option'] = orjson.OPT_INDENT_2
if 'sort_keys' in kwargs:
raise TypeError(
"orjson does not accept the sort_keys parameter. "
"If you need to pass sort_keys, set force_use_builtin_json=True "
"to use Python's built-in json library instead of orjson.")
return orjson.dumps(
item,
default=json_convertor_default(default_mapping=default_mapping),
Expand Down
8 changes: 8 additions & 0 deletions tests/test_serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ def test_serialization_text(self):
jsoned = ddiff.to_json()
assert "world" in jsoned

def test_serialization_text_force_builtin_json(self):
ddiff = DeepDiff(t1, t2)
with pytest.raises(TypeError) as excinfo:
jsoned = ddiff.to_json(sort_keys=True)
assert str(excinfo.value).startswith("orjson does not accept the sort_keys parameter.")
jsoned = ddiff.to_json(sort_keys=True, force_use_builtin_json=True)
assert "world" in jsoned

def test_deserialization(self):
ddiff = DeepDiff(t1, t2)
jsoned = ddiff.to_json_pickle()
Expand Down

0 comments on commit 42fd42d

Please sign in to comment.