##// END OF EJS Templates
libs: ext_json improvements for orjson support
super-admin -
r5073:4a99ba09 default
parent child Browse files
Show More
@@ -1,86 +1,95 b''
1 import datetime
1 import datetime
2 import decimal
2 import decimal
3 import functools
3 import functools
4 # we keep simplejson for having dump functionality still
4 import json as stdlib_json
5 # orjson doesn't support it
6 import simplejson as sjson
7
5
8 import orjson
6 try:
9 import orjson as json
7 # we keep simplejson for having dump functionality still
8 # orjson doesn't support it
9 import simplejson as sjson
10 except ImportError:
11 sjson = stdlib_json
12
13 try:
14 import orjson
15 import orjson as json
16 except ImportError:
17 json = stdlib_json
10
18
11
19
12 from rhodecode.lib.datelib import is_aware
20 from rhodecode.lib.datelib import is_aware
13 from rhodecode.lib.str_utils import safe_str
21 from rhodecode.lib.str_utils import safe_str
14
22
15 try:
23 try:
16 import rhodecode.translation
24 import rhodecode.translation
17 except ImportError:
25 except ImportError:
18 rhodecode = None
26 rhodecode = None
19
27
20 __all__ = ['json']
28 __all__ = ['json']
21
29
22
30
23 def _obj_dump(obj):
31 def _obj_dump(obj):
24 """
32 """
25 Custom function for dumping objects to JSON, if obj has __json__ attribute
33 Custom function for dumping objects to JSON, if obj has __json__ attribute
26 or method defined it will be used for serialization
34 or method defined it will be used for serialization
27
35
28 :param obj:
36 :param obj:
29 """
37 """
38
39 if isinstance(obj, set):
40 return list(obj)
30 # See "Date Time String Format" in the ECMA-262 specification.
41 # See "Date Time String Format" in the ECMA-262 specification.
31 # some code borrowed from django 1.4
42 # some code borrowed from django 1.4
32 if isinstance(obj, set):
33 return list(obj)
34 elif isinstance(obj, datetime.datetime):
43 elif isinstance(obj, datetime.datetime):
35 r = obj.isoformat()
44 r = obj.isoformat()
36 if isinstance(obj.microsecond, int):
45 if isinstance(obj.microsecond, int):
37 r = r[:23] + r[26:]
46 r = r[:23] + r[26:]
38 if r.endswith('+00:00'):
47 if r.endswith('+00:00'):
39 r = r[:-6] + 'Z'
48 r = r[:-6] + 'Z'
40 return r
49 return r
41 elif isinstance(obj, datetime.date):
50 elif isinstance(obj, datetime.date):
42 return obj.isoformat()
51 return obj.isoformat()
52 elif isinstance(obj, decimal.Decimal):
53 return str(obj)
43 elif isinstance(obj, datetime.time):
54 elif isinstance(obj, datetime.time):
44 if is_aware(obj):
55 if is_aware(obj):
45 raise TypeError("Time-zone aware times are not JSON serializable")
56 raise TypeError("Time-zone aware times are not JSON serializable")
46 r = obj.isoformat()
57 r = obj.isoformat()
47 if isinstance(obj.microsecond, int):
58 if isinstance(obj.microsecond, int):
48 r = r[:12]
59 r = r[:12]
49 return r
60 return r
50 elif hasattr(obj, '__json__'):
61 elif hasattr(obj, '__json__'):
51 if callable(obj.__json__):
62 if callable(obj.__json__):
52 return obj.__json__()
63 return obj.__json__()
53 else:
64 else:
54 return obj.__json__
65 return obj.__json__
55 elif isinstance(obj, decimal.Decimal):
56 return str(obj)
57 elif isinstance(obj, complex):
66 elif isinstance(obj, complex):
58 return [obj.real, obj.imag]
67 return [obj.real, obj.imag]
59 elif rhodecode and isinstance(obj, rhodecode.translation._LazyString):
68 elif rhodecode and isinstance(obj, rhodecode.translation._LazyString):
60 return obj.eval()
69 return obj.eval()
61 else:
70 else:
62 raise TypeError(repr(obj) + " is not JSON serializable")
71 raise TypeError(repr(obj) + " is not JSON serializable")
63
72
64
73
65 sjson.dumps = functools.partial(sjson.dumps, default=_obj_dump)
74 sjson.dumps = functools.partial(sjson.dumps, default=_obj_dump)
66 sjson.dump = functools.partial(sjson.dump, default=_obj_dump)
75 sjson.dump = functools.partial(sjson.dump, default=_obj_dump)
67
76
68 json.dumps = functools.partial(json.dumps, default=_obj_dump, option=orjson.OPT_NON_STR_KEYS)
77 json.dumps = functools.partial(json.dumps, default=_obj_dump, option=orjson.OPT_NON_STR_KEYS)
69 json.dump = functools.partial(sjson.dump, default=_obj_dump)
78 json.dump = functools.partial(sjson.dump, default=_obj_dump)
70
79
71
80
72 def formatted_json(*args, **kwargs):
81 def formatted_json(*args, **kwargs):
73 # alias for formatted json
82 # alias for formatted json
74 opts = orjson.OPT_NON_STR_KEYS | orjson.OPT_INDENT_2 | orjson.OPT_SORT_KEYS
83 opts = orjson.OPT_NON_STR_KEYS | orjson.OPT_INDENT_2 | orjson.OPT_SORT_KEYS
75 return functools.partial(json.dumps, option=opts)(*args, **kwargs)
84 return functools.partial(json.dumps, option=opts)(*args, **kwargs)
76
85
77
86
78 def formatted_str_json(*args, **kwargs):
87 def formatted_str_json(*args, **kwargs):
79 opts = orjson.OPT_NON_STR_KEYS | orjson.OPT_INDENT_2 | orjson.OPT_SORT_KEYS
88 opts = orjson.OPT_NON_STR_KEYS | orjson.OPT_INDENT_2 | orjson.OPT_SORT_KEYS
80 closure = functools.partial(json.dumps, option=opts)
89 closure = functools.partial(json.dumps, option=opts)
81 return safe_str(closure(*args, **kwargs))
90 return safe_str(closure(*args, **kwargs))
82
91
83
92
84 def str_json(*args, **kwargs):
93 def str_json(*args, **kwargs):
85 closure = functools.partial(json.dumps)
94 closure = functools.partial(json.dumps)
86 return safe_str(closure(*args, **kwargs))
95 return safe_str(closure(*args, **kwargs))
General Comments 0
You need to be logged in to leave comments. Login now