1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
import re
import json
MYPY = False
if MYPY:
# MYPY is set to True when run under Mypy.
from typing import Any, AnyStr, Callable, Dict, IO, Text
__all__ = ["load", "dump_local", "dump_local", "dump_dist", "dumps_dist"]
try:
import ujson
except ImportError:
has_ujson = False
else:
has_ujson = True
#
# load
#
if has_ujson:
load = ujson.load # type: Callable[[IO[AnyStr]], Any]
else:
load = json.load
#
# loads
#
if has_ujson:
loads = ujson.loads # type: Callable[[AnyStr], Any]
else:
loads = json.loads
#
# dump/dumps_local options for some libraries
#
_ujson_dump_local_kwargs = {
'ensure_ascii': False,
'escape_forward_slashes': False,
'indent': 1,
'reject_bytes': True,
} # type: Dict[str, Any]
_json_dump_local_kwargs = {
'ensure_ascii': False,
'indent': 1,
'separators': (',', ': '),
} # type: Dict[str, Any]
#
# dump_local (for local, non-distributed usage of JSON)
#
if has_ujson:
def dump_local(obj, fp):
# type: (Any, IO[str]) -> None
return ujson.dump(obj, fp, **_ujson_dump_local_kwargs)
else:
def dump_local(obj, fp):
# type: (Any, IO[str]) -> None
return json.dump(obj, fp, **_json_dump_local_kwargs)
#
# dumps_local (for local, non-distributed usage of JSON)
#
if has_ujson:
def dumps_local(obj):
# type: (Any) -> Text
return ujson.dumps(obj, **_ujson_dump_local_kwargs)
else:
def dumps_local(obj):
# type: (Any) -> Text
return json.dumps(obj, **_json_dump_local_kwargs)
#
# dump/dumps_dist (for distributed usage of JSON where files should safely roundtrip)
#
_ujson_dump_dist_kwargs = {
'sort_keys': True,
'indent': 1,
'reject_bytes': True,
} # type: Dict[str, Any]
_json_dump_dist_kwargs = {
'sort_keys': True,
'indent': 1,
'separators': (',', ': '),
} # type: Dict[str, Any]
if has_ujson:
if ujson.dumps([], indent=1) == "[]":
# optimistically see if https://github.com/ultrajson/ultrajson/issues/429 is fixed
def _ujson_fixup(s):
# type: (str) -> str
return s
else:
_ujson_fixup_re = re.compile(r"([\[{])[\n\x20]+([}\]])")
def _ujson_fixup(s):
# type: (str) -> str
return _ujson_fixup_re.sub(
lambda m: m.group(1) + m.group(2),
s
)
def dump_dist(obj, fp):
# type: (Any, IO[str]) -> None
fp.write(_ujson_fixup(ujson.dumps(obj, **_ujson_dump_dist_kwargs)))
def dumps_dist(obj):
# type: (Any) -> Text
return _ujson_fixup(ujson.dumps(obj, **_ujson_dump_dist_kwargs))
else:
def dump_dist(obj, fp):
# type: (Any, IO[str]) -> None
json.dump(obj, fp, **_json_dump_dist_kwargs)
def dumps_dist(obj):
# type: (Any) -> Text
return json.dumps(obj, **_json_dump_dist_kwargs)
|