Skip to content

Commit 91e9f24

Browse files
committed
let's use orjson
1 parent 2a2bd73 commit 91e9f24

File tree

3 files changed

+21
-6
lines changed

3 files changed

+21
-6
lines changed

deepdiff/serialization.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import io
44
import os
55
import json
6+
import orjson
67
import uuid
78
import logging
89
import re # NOQA
@@ -181,7 +182,7 @@ def to_json(self, default_mapping=None, **kwargs):
181182
'{"type_changes": {"root": {"old_type": "A", "new_type": "B", "old_value": "obj A", "new_value": "obj B"}}}'
182183
"""
183184
dic = self.to_dict(view_override=TEXT_VIEW)
184-
return json.dumps(dic, default=json_convertor_default(default_mapping=default_mapping), **kwargs)
185+
return json_dumps(dic, default_mapping=default_mapping, **kwargs)
185186

186187
def to_dict(self, view_override=None):
187188
"""
@@ -410,7 +411,7 @@ def load_path_content(path, file_type=None):
410411
file_type = path.split('.')[-1]
411412
if file_type == 'json':
412413
with open(path, 'r') as the_file:
413-
content = json.load(the_file)
414+
content = json_loads(the_file.read())
414415
elif file_type in {'yaml', 'yml'}:
415416
if yaml is None: # pragma: no cover.
416417
raise ImportError('Pyyaml needs to be installed.') # pragma: no cover.
@@ -474,7 +475,8 @@ def save_content_to_path(content, path, file_type=None, keep_backup=True):
474475
def _save_content(content, path, file_type, keep_backup=True):
475476
if file_type == 'json':
476477
with open(path, 'w') as the_file:
477-
content = json.dump(content, the_file)
478+
content = json_dumps(content)
479+
the_file.write(content)
478480
elif file_type in {'yaml', 'yml'}:
479481
if yaml is None: # pragma: no cover.
480482
raise ImportError('Pyyaml needs to be installed.') # pragma: no cover.
@@ -504,8 +506,15 @@ def _save_content(content, path, file_type, keep_backup=True):
504506
return content
505507

506508

509+
def _serialize_decimal(value):
510+
if value.as_tuple().exponent == 0:
511+
return int(value)
512+
else:
513+
return float(value)
514+
515+
507516
JSON_CONVERTOR = {
508-
decimal.Decimal: float,
517+
decimal.Decimal: _serialize_decimal,
509518
ordered_set.OrderedSet: list,
510519
type: lambda x: x.__name__,
511520
bytes: lambda x: x.decode('utf-8'),
@@ -552,7 +561,10 @@ def json_dumps(item, default_mapping=None, **kwargs):
552561
but the output it makes is a byte object and Postgres couldn't directly use it without
553562
encoding to str. So I switched back to json.
554563
"""
555-
return json.dumps(item, default=json_convertor_default(default_mapping=default_mapping), **kwargs)
564+
return orjson.dumps(
565+
item,
566+
default=json_convertor_default(default_mapping=default_mapping),
567+
**kwargs).decode(encoding='utf-8')
556568

557569

558570
json_loads = partial(json.loads, cls=JSONDecoder)

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
ordered-set>=4.0.2,<4.2.0
2+
orjson

tests/test_serialization.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,8 +318,10 @@ def test_pretty_form_method(self, expected, verbose_level):
318318
@pytest.mark.parametrize('test_num, value', [
319319
(1, {'10': None}),
320320
(2, {"type_changes": {"root": {"old_type": None, "new_type": list, "new_value": ["你好", 2, 3, 5]}}}),
321+
(3, {'10': Decimal(2017)}),
322+
(4, Decimal(2017.1)),
321323
])
322324
def test_json_dumps_and_loads(self, test_num, value):
323325
serialized = json_dumps(value)
324326
back = json_loads(serialized)
325-
assert value == back, f"test_json_dumps_and_loads tesst #{test_num} failed"
327+
assert value == back, f"test_json_dumps_and_loads test #{test_num} failed"

0 commit comments

Comments
 (0)