codekingpro/portable-devtools
114k
1r"""JSON (JavaScript Object Notation) <https://json.org> is a subset of2JavaScript syntax (ECMA-262 3rd edition) used as a lightweight data3interchange format.4 5:mod:`json` exposes an API familiar to users of the standard library6:mod:`marshal` and :mod:`pickle` modules. It is derived from a7version of the externally maintained simplejson library.8 9Encoding basic Python object hierarchies::10 11 >>> import json12 >>> json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}])13 '["foo", {"bar": ["baz", null, 1.0, 2]}]'14 >>> print(json.dumps("\"foo\bar"))15 "\"foo\bar"16 >>> print(json.dumps('\u1234'))17 "\u1234"18 >>> print(json.dumps('\\'))19 "\\"20 >>> print(json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True))21 {"a": 0, "b": 0, "c": 0}22 >>> from io import StringIO23 >>> io = StringIO()24 >>> json.dump(['streaming API'], io)25 >>> io.getvalue()26 '["streaming API"]'27 28Compact encoding::29 30 >>> import json31 >>> mydict = {'4': 5, '6': 7}32 >>> json.dumps([1,2,3,mydict], separators=(',', ':'))33 '[1,2,3,{"4":5,"6":7}]'34 35Pretty printing::36 37 >>> import json38 >>> print(json.dumps({'4': 5, '6': 7}, sort_keys=True, indent=4))39 {40 "4": 5,41 "6": 742 }43 44Decoding JSON::45 46 >>> import json47 >>> obj = ['foo', {'bar': ['baz', None, 1.0, 2]}]48 >>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]') == obj49 True50 >>> json.loads('"\\"foo\\bar"') == '"foo\x08ar'51 True52 >>> from io import StringIO53 >>> io = StringIO('["streaming API"]')54 >>> json.load(io)[0] == 'streaming API'55 True56 57Specializing JSON object decoding::58 59 >>> import json60 >>> def as_complex(dct):61 ... if '__complex__' in dct:62 ... return complex(dct['real'], dct['imag'])63 ... return dct64 ...65 >>> json.loads('{"__complex__": true, "real": 1, "imag": 2}',66 ... object_hook=as_complex)67 (1+2j)68 >>> from decimal import Decimal69 >>> json.loads('1.1', parse_float=Decimal) == Decimal('1.1')70 True71 72Specializing JSON object encoding::73 74 >>> import json75 >>> def encode_complex(obj):76 ... if isinstance(obj, complex):77 ... return [obj.real, obj.imag]78 ... raise TypeError(f'Object of type {obj.__class__.__name__} '79 ... f'is not JSON serializable')80 ...81 >>> json.dumps(2 + 1j, default=encode_complex)82 '[2.0, 1.0]'83 >>> json.JSONEncoder(default=encode_complex).encode(2 + 1j)84 '[2.0, 1.0]'85 >>> ''.join(json.JSONEncoder(default=encode_complex).iterencode(2 + 1j))86 '[2.0, 1.0]'87 88 89Using json from the shell to validate and pretty-print::90 91 $ echo '{"json":"obj"}' | python -m json92 {93 "json": "obj"94 }95 $ echo '{ 1.2:3.4}' | python -m json96 Expecting property name enclosed in double quotes: line 1 column 3 (char 2)97"""98__version__ = '2.0.9'99__all__ = [100 'dump', 'dumps', 'load', 'loads',101 'JSONDecoder', 'JSONDecodeError', 'JSONEncoder',102]103 104__author__ = 'Bob Ippolito <bob@redivi.com>'105 106from .decoder import JSONDecoder, JSONDecodeError107from .encoder import JSONEncoder108import codecs109 110_default_encoder = JSONEncoder(111 skipkeys=False,112 ensure_ascii=True,113 check_circular=True,114 allow_nan=True,115 indent=None,116 separators=None,117 default=None,118)119 120def dump(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True,121 allow_nan=True, cls=None, indent=None, separators=None,122 default=None, sort_keys=False, **kw):123 """Serialize ``obj`` as a JSON formatted stream to ``fp`` (a124 ``.write()``-supporting file-like object).125 126 If ``skipkeys`` is true then ``dict`` keys that are not basic types127 (``str``, ``int``, ``float``, ``bool``, ``None``) will be skipped128 instead of raising a ``TypeError``.129 130 If ``ensure_ascii`` is false, then the strings written to ``fp`` can131 contain non-ASCII and non-printable characters if they appear in strings132 contained in ``obj``. Otherwise, all such characters are escaped in JSON133 strings.134 135 If ``check_circular`` is false, then the circular reference check136 for container types will be skipped and a circular reference will137 result in an ``RecursionError`` (or worse).138 139 If ``allow_nan`` is false, then it will be a ``ValueError`` to140 serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``)141 in strict compliance of the JSON specification, instead of using the142 JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``).143 144 If ``indent`` is a non-negative integer, then JSON array elements and145 object members will be pretty-printed with that indent level. An indent146 level of 0 will only insert newlines. ``None`` is the most compact147 representation.148 149 If specified, ``separators`` should be an ``(item_separator,150 key_separator)`` tuple. The default is ``(', ', ': ')`` if *indent* is151 ``None`` and ``(',', ': ')`` otherwise. To get the most compact JSON152 representation, you should specify ``(',', ':')`` to eliminate153 whitespace.154 155 ``default(obj)`` is a function that should return a serializable version156 of obj or raise TypeError. The default simply raises TypeError.157 158 If *sort_keys* is true (default: ``False``), then the output of159 dictionaries will be sorted by key.160 161 To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the162 ``.default()`` method to serialize additional types), specify it with163 the ``cls`` kwarg; otherwise ``JSONEncoder`` is used.164 165 """166 # cached encoder167 if (not skipkeys and ensure_ascii and168 check_circular and allow_nan and169 cls is None and indent is None and separators is None and170 default is None and not sort_keys and not kw):171 iterable = _default_encoder.iterencode(obj)172 else:173 if cls is None:174 cls = JSONEncoder175 iterable = cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii,176 check_circular=check_circular, allow_nan=allow_nan, indent=indent,177 separators=separators,178 default=default, sort_keys=sort_keys, **kw).iterencode(obj)179 # could accelerate with writelines in some versions of Python, at180 # a debuggability cost181 for chunk in iterable:182 fp.write(chunk)183 184 185def dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True,186 allow_nan=True, cls=None, indent=None, separators=None,187 default=None, sort_keys=False, **kw):188 """Serialize ``obj`` to a JSON formatted ``str``.189 190 If ``skipkeys`` is true then ``dict`` keys that are not basic types191 (``str``, ``int``, ``float``, ``bool``, ``None``) will be skipped192 instead of raising a ``TypeError``.193 194 If ``ensure_ascii`` is false, then the return value can contain195 non-ASCII and non-printable characters if they appear in strings196 contained in ``obj``. Otherwise, all such characters are escaped in197 JSON strings.198 199 If ``check_circular`` is false, then the circular reference check200 for container types will be skipped and a circular reference will201 result in an ``RecursionError`` (or worse).202 203 If ``allow_nan`` is false, then it will be a ``ValueError`` to204 serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in205 strict compliance of the JSON specification, instead of using the206 JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``).207 208 If ``indent`` is a non-negative integer, then JSON array elements and209 object members will be pretty-printed with that indent level. An indent210 level of 0 will only insert newlines. ``None`` is the most compact211 representation.212 213 If specified, ``separators`` should be an ``(item_separator,214 key_separator)`` tuple. The default is ``(', ', ': ')`` if *indent* is215 ``None`` and ``(',', ': ')`` otherwise. To get the most compact JSON216 representation, you should specify ``(',', ':')`` to eliminate217 whitespace.218 219 ``default(obj)`` is a function that should return a serializable version220 of obj or raise TypeError. The default simply raises TypeError.221 222 If *sort_keys* is true (default: ``False``), then the output of223 dictionaries will be sorted by key.224 225 To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the226 ``.default()`` method to serialize additional types), specify it with227 the ``cls`` kwarg; otherwise ``JSONEncoder`` is used.228 229 """230 # cached encoder231 if (not skipkeys and ensure_ascii and232 check_circular and allow_nan and233 cls is None and indent is None and separators is None and234 default is None and not sort_keys and not kw):235 return _default_encoder.encode(obj)236 if cls is None:237 cls = JSONEncoder238 return cls(239 skipkeys=skipkeys, ensure_ascii=ensure_ascii,240 check_circular=check_circular, allow_nan=allow_nan, indent=indent,241 separators=separators, default=default, sort_keys=sort_keys,242 **kw).encode(obj)243 244 245_default_decoder = JSONDecoder(object_hook=None, object_pairs_hook=None)246 247 248def detect_encoding(b):249 bstartswith = b.startswith250 if bstartswith((codecs.BOM_UTF32_BE, codecs.BOM_UTF32_LE)):251 return 'utf-32'252 if bstartswith((codecs.BOM_UTF16_BE, codecs.BOM_UTF16_LE)):253 return 'utf-16'254 if bstartswith(codecs.BOM_UTF8):255 return 'utf-8-sig'256 257 if len(b) >= 4:258 if not b[0]:259 # 00 00 -- -- - utf-32-be260 # 00 XX -- -- - utf-16-be261 return 'utf-16-be' if b[1] else 'utf-32-be'262 if not b[1]:263 # XX 00 00 00 - utf-32-le264 # XX 00 00 XX - utf-16-le265 # XX 00 XX -- - utf-16-le266 return 'utf-16-le' if b[2] or b[3] else 'utf-32-le'267 elif len(b) == 2:268 if not b[0]:269 # 00 XX - utf-16-be270 return 'utf-16-be'271 if not b[1]:272 # XX 00 - utf-16-le273 return 'utf-16-le'274 # default275 return 'utf-8'276 277 278def load(fp, *, cls=None, object_hook=None, parse_float=None,279 parse_int=None, parse_constant=None, object_pairs_hook=None, **kw):280 """Deserialize ``fp`` (a ``.read()``-supporting file-like object containing281 a JSON document) to a Python object.282 283 ``object_hook`` is an optional function that will be called with the284 result of any object literal decode (a ``dict``). The return value of285 ``object_hook`` will be used instead of the ``dict``. This feature286 can be used to implement custom decoders (e.g. JSON-RPC class hinting).287 288 ``object_pairs_hook`` is an optional function that will be called with289 the result of any object literal decoded with an ordered list of pairs.290 The return value of ``object_pairs_hook`` will be used instead of the291 ``dict``. This feature can be used to implement custom decoders. If292 ``object_hook`` is also defined, the ``object_pairs_hook`` takes293 priority.294 295 To use a custom ``JSONDecoder`` subclass, specify it with the ``cls``296 kwarg; otherwise ``JSONDecoder`` is used.297 """298 return loads(fp.read(),299 cls=cls, object_hook=object_hook,300 parse_float=parse_float, parse_int=parse_int,301 parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw)302 303 304def loads(s, *, cls=None, object_hook=None, parse_float=None,305 parse_int=None, parse_constant=None, object_pairs_hook=None, **kw):306 """Deserialize ``s`` (a ``str``, ``bytes`` or ``bytearray`` instance307 containing a JSON document) to a Python object.308 309 ``object_hook`` is an optional function that will be called with the310 result of any object literal decode (a ``dict``). The return value of311 ``object_hook`` will be used instead of the ``dict``. This feature312 can be used to implement custom decoders (e.g. JSON-RPC class hinting).313 314 ``object_pairs_hook`` is an optional function that will be called with315 the result of any object literal decoded with an ordered list of pairs.316 The return value of ``object_pairs_hook`` will be used instead of the317 ``dict``. This feature can be used to implement custom decoders. If318 ``object_hook`` is also defined, the ``object_pairs_hook`` takes319 priority.320 321 ``parse_float``, if specified, will be called with the string322 of every JSON float to be decoded. By default this is equivalent to323 float(num_str). This can be used to use another datatype or parser324 for JSON floats (e.g. decimal.Decimal).325 326 ``parse_int``, if specified, will be called with the string327 of every JSON int to be decoded. By default this is equivalent to328 int(num_str). This can be used to use another datatype or parser329 for JSON integers (e.g. float).330 331 ``parse_constant``, if specified, will be called with one of the332 following strings: -Infinity, Infinity, NaN.333 This can be used to raise an exception if invalid JSON numbers334 are encountered.335 336 To use a custom ``JSONDecoder`` subclass, specify it with the ``cls``337 kwarg; otherwise ``JSONDecoder`` is used.338 """339 if isinstance(s, str):340 if s.startswith('\ufeff'):341 raise JSONDecodeError("Unexpected UTF-8 BOM (decode using utf-8-sig)",342 s, 0)343 else:344 if not isinstance(s, (bytes, bytearray)):345 raise TypeError(f'the JSON object must be str, bytes or bytearray, '346 f'not {s.__class__.__name__}')347 s = s.decode(detect_encoding(s), 'surrogatepass')348 349 if (cls is None and object_hook is None and350 parse_int is None and parse_float is None and351 parse_constant is None and object_pairs_hook is None and not kw):352 return _default_decoder.decode(s)353 if cls is None:354 cls = JSONDecoder355 if object_hook is not None:356 kw['object_hook'] = object_hook357 if object_pairs_hook is not None:358 kw['object_pairs_hook'] = object_pairs_hook359 if parse_float is not None:360 kw['parse_float'] = parse_float361 if parse_int is not None:362 kw['parse_int'] = parse_int363 if parse_constant is not None:364 kw['parse_constant'] = parse_constant365 return cls(**kw).decode(s)366 