addon-sdk/source/python-lib/simplejson/__init__.py

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 r"""
michael@0 2 A simple, fast, extensible JSON encoder and decoder
michael@0 3
michael@0 4 JSON (JavaScript Object Notation) <http://json.org> is a subset of
michael@0 5 JavaScript syntax (ECMA-262 3rd edition) used as a lightweight data
michael@0 6 interchange format.
michael@0 7
michael@0 8 simplejson exposes an API familiar to uses of the standard library
michael@0 9 marshal and pickle modules.
michael@0 10
michael@0 11 Encoding basic Python object hierarchies::
michael@0 12
michael@0 13 >>> import simplejson
michael@0 14 >>> simplejson.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}])
michael@0 15 '["foo", {"bar": ["baz", null, 1.0, 2]}]'
michael@0 16 >>> print simplejson.dumps("\"foo\bar")
michael@0 17 "\"foo\bar"
michael@0 18 >>> print simplejson.dumps(u'\u1234')
michael@0 19 "\u1234"
michael@0 20 >>> print simplejson.dumps('\\')
michael@0 21 "\\"
michael@0 22 >>> print simplejson.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True)
michael@0 23 {"a": 0, "b": 0, "c": 0}
michael@0 24 >>> from StringIO import StringIO
michael@0 25 >>> io = StringIO()
michael@0 26 >>> simplejson.dump(['streaming API'], io)
michael@0 27 >>> io.getvalue()
michael@0 28 '["streaming API"]'
michael@0 29
michael@0 30 Compact encoding::
michael@0 31
michael@0 32 >>> import simplejson
michael@0 33 >>> simplejson.dumps([1,2,3,{'4': 5, '6': 7}], separators=(',',':'))
michael@0 34 '[1,2,3,{"4":5,"6":7}]'
michael@0 35
michael@0 36 Pretty printing::
michael@0 37
michael@0 38 >>> import simplejson
michael@0 39 >>> print simplejson.dumps({'4': 5, '6': 7}, sort_keys=True, indent=4)
michael@0 40 {
michael@0 41 "4": 5,
michael@0 42 "6": 7
michael@0 43 }
michael@0 44
michael@0 45 Decoding JSON::
michael@0 46
michael@0 47 >>> import simplejson
michael@0 48 >>> simplejson.loads('["foo", {"bar":["baz", null, 1.0, 2]}]')
michael@0 49 [u'foo', {u'bar': [u'baz', None, 1.0, 2]}]
michael@0 50 >>> simplejson.loads('"\\"foo\\bar"')
michael@0 51 u'"foo\x08ar'
michael@0 52 >>> from StringIO import StringIO
michael@0 53 >>> io = StringIO('["streaming API"]')
michael@0 54 >>> simplejson.load(io)
michael@0 55 [u'streaming API']
michael@0 56
michael@0 57 Specializing JSON object decoding::
michael@0 58
michael@0 59 >>> import simplejson
michael@0 60 >>> def as_complex(dct):
michael@0 61 ... if '__complex__' in dct:
michael@0 62 ... return complex(dct['real'], dct['imag'])
michael@0 63 ... return dct
michael@0 64 ...
michael@0 65 >>> simplejson.loads('{"__complex__": true, "real": 1, "imag": 2}',
michael@0 66 ... object_hook=as_complex)
michael@0 67 (1+2j)
michael@0 68 >>> import decimal
michael@0 69 >>> simplejson.loads('1.1', parse_float=decimal.Decimal)
michael@0 70 Decimal("1.1")
michael@0 71
michael@0 72 Extending JSONEncoder::
michael@0 73
michael@0 74 >>> import simplejson
michael@0 75 >>> class ComplexEncoder(simplejson.JSONEncoder):
michael@0 76 ... def default(self, obj):
michael@0 77 ... if isinstance(obj, complex):
michael@0 78 ... return [obj.real, obj.imag]
michael@0 79 ... return simplejson.JSONEncoder.default(self, obj)
michael@0 80 ...
michael@0 81 >>> dumps(2 + 1j, cls=ComplexEncoder)
michael@0 82 '[2.0, 1.0]'
michael@0 83 >>> ComplexEncoder().encode(2 + 1j)
michael@0 84 '[2.0, 1.0]'
michael@0 85 >>> list(ComplexEncoder().iterencode(2 + 1j))
michael@0 86 ['[', '2.0', ', ', '1.0', ']']
michael@0 87
michael@0 88
michael@0 89 Using simplejson from the shell to validate and
michael@0 90 pretty-print::
michael@0 91
michael@0 92 $ echo '{"json":"obj"}' | python -msimplejson.tool
michael@0 93 {
michael@0 94 "json": "obj"
michael@0 95 }
michael@0 96 $ echo '{ 1.2:3.4}' | python -msimplejson.tool
michael@0 97 Expecting property name: line 1 column 2 (char 2)
michael@0 98
michael@0 99 Note that the JSON produced by this module's default settings
michael@0 100 is a subset of YAML, so it may be used as a serializer for that as well.
michael@0 101 """
michael@0 102 __version__ = '1.9.2'
michael@0 103 __all__ = [
michael@0 104 'dump', 'dumps', 'load', 'loads',
michael@0 105 'JSONDecoder', 'JSONEncoder',
michael@0 106 ]
michael@0 107
michael@0 108 if __name__ == '__main__':
michael@0 109 import warnings
michael@0 110 warnings.warn('python -msimplejson is deprecated, use python -msiplejson.tool', DeprecationWarning)
michael@0 111 from simplejson.decoder import JSONDecoder
michael@0 112 from simplejson.encoder import JSONEncoder
michael@0 113 else:
michael@0 114 from decoder import JSONDecoder
michael@0 115 from encoder import JSONEncoder
michael@0 116
michael@0 117 _default_encoder = JSONEncoder(
michael@0 118 skipkeys=False,
michael@0 119 ensure_ascii=True,
michael@0 120 check_circular=True,
michael@0 121 allow_nan=True,
michael@0 122 indent=None,
michael@0 123 separators=None,
michael@0 124 encoding='utf-8',
michael@0 125 default=None,
michael@0 126 )
michael@0 127
michael@0 128 def dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True,
michael@0 129 allow_nan=True, cls=None, indent=None, separators=None,
michael@0 130 encoding='utf-8', default=None, **kw):
michael@0 131 """
michael@0 132 Serialize ``obj`` as a JSON formatted stream to ``fp`` (a
michael@0 133 ``.write()``-supporting file-like object).
michael@0 134
michael@0 135 If ``skipkeys`` is ``True`` then ``dict`` keys that are not basic types
michael@0 136 (``str``, ``unicode``, ``int``, ``long``, ``float``, ``bool``, ``None``)
michael@0 137 will be skipped instead of raising a ``TypeError``.
michael@0 138
michael@0 139 If ``ensure_ascii`` is ``False``, then the some chunks written to ``fp``
michael@0 140 may be ``unicode`` instances, subject to normal Python ``str`` to
michael@0 141 ``unicode`` coercion rules. Unless ``fp.write()`` explicitly
michael@0 142 understands ``unicode`` (as in ``codecs.getwriter()``) this is likely
michael@0 143 to cause an error.
michael@0 144
michael@0 145 If ``check_circular`` is ``False``, then the circular reference check
michael@0 146 for container types will be skipped and a circular reference will
michael@0 147 result in an ``OverflowError`` (or worse).
michael@0 148
michael@0 149 If ``allow_nan`` is ``False``, then it will be a ``ValueError`` to
michael@0 150 serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``)
michael@0 151 in strict compliance of the JSON specification, instead of using the
michael@0 152 JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``).
michael@0 153
michael@0 154 If ``indent`` is a non-negative integer, then JSON array elements and object
michael@0 155 members will be pretty-printed with that indent level. An indent level
michael@0 156 of 0 will only insert newlines. ``None`` is the most compact representation.
michael@0 157
michael@0 158 If ``separators`` is an ``(item_separator, dict_separator)`` tuple
michael@0 159 then it will be used instead of the default ``(', ', ': ')`` separators.
michael@0 160 ``(',', ':')`` is the most compact JSON representation.
michael@0 161
michael@0 162 ``encoding`` is the character encoding for str instances, default is UTF-8.
michael@0 163
michael@0 164 ``default(obj)`` is a function that should return a serializable version
michael@0 165 of obj or raise TypeError. The default simply raises TypeError.
michael@0 166
michael@0 167 To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the
michael@0 168 ``.default()`` method to serialize additional types), specify it with
michael@0 169 the ``cls`` kwarg.
michael@0 170 """
michael@0 171 # cached encoder
michael@0 172 if (skipkeys is False and ensure_ascii is True and
michael@0 173 check_circular is True and allow_nan is True and
michael@0 174 cls is None and indent is None and separators is None and
michael@0 175 encoding == 'utf-8' and default is None and not kw):
michael@0 176 iterable = _default_encoder.iterencode(obj)
michael@0 177 else:
michael@0 178 if cls is None:
michael@0 179 cls = JSONEncoder
michael@0 180 iterable = cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii,
michael@0 181 check_circular=check_circular, allow_nan=allow_nan, indent=indent,
michael@0 182 separators=separators, encoding=encoding,
michael@0 183 default=default, **kw).iterencode(obj)
michael@0 184 # could accelerate with writelines in some versions of Python, at
michael@0 185 # a debuggability cost
michael@0 186 for chunk in iterable:
michael@0 187 fp.write(chunk)
michael@0 188
michael@0 189
michael@0 190 def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True,
michael@0 191 allow_nan=True, cls=None, indent=None, separators=None,
michael@0 192 encoding='utf-8', default=None, **kw):
michael@0 193 """
michael@0 194 Serialize ``obj`` to a JSON formatted ``str``.
michael@0 195
michael@0 196 If ``skipkeys`` is ``True`` then ``dict`` keys that are not basic types
michael@0 197 (``str``, ``unicode``, ``int``, ``long``, ``float``, ``bool``, ``None``)
michael@0 198 will be skipped instead of raising a ``TypeError``.
michael@0 199
michael@0 200 If ``ensure_ascii`` is ``False``, then the return value will be a
michael@0 201 ``unicode`` instance subject to normal Python ``str`` to ``unicode``
michael@0 202 coercion rules instead of being escaped to an ASCII ``str``.
michael@0 203
michael@0 204 If ``check_circular`` is ``False``, then the circular reference check
michael@0 205 for container types will be skipped and a circular reference will
michael@0 206 result in an ``OverflowError`` (or worse).
michael@0 207
michael@0 208 If ``allow_nan`` is ``False``, then it will be a ``ValueError`` to
michael@0 209 serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in
michael@0 210 strict compliance of the JSON specification, instead of using the
michael@0 211 JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``).
michael@0 212
michael@0 213 If ``indent`` is a non-negative integer, then JSON array elements and
michael@0 214 object members will be pretty-printed with that indent level. An indent
michael@0 215 level of 0 will only insert newlines. ``None`` is the most compact
michael@0 216 representation.
michael@0 217
michael@0 218 If ``separators`` is an ``(item_separator, dict_separator)`` tuple
michael@0 219 then it will be used instead of the default ``(', ', ': ')`` separators.
michael@0 220 ``(',', ':')`` is the most compact JSON representation.
michael@0 221
michael@0 222 ``encoding`` is the character encoding for str instances, default is UTF-8.
michael@0 223
michael@0 224 ``default(obj)`` is a function that should return a serializable version
michael@0 225 of obj or raise TypeError. The default simply raises TypeError.
michael@0 226
michael@0 227 To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the
michael@0 228 ``.default()`` method to serialize additional types), specify it with
michael@0 229 the ``cls`` kwarg.
michael@0 230 """
michael@0 231 # cached encoder
michael@0 232 if (skipkeys is False and ensure_ascii is True and
michael@0 233 check_circular is True and allow_nan is True and
michael@0 234 cls is None and indent is None and separators is None and
michael@0 235 encoding == 'utf-8' and default is None and not kw):
michael@0 236 return _default_encoder.encode(obj)
michael@0 237 if cls is None:
michael@0 238 cls = JSONEncoder
michael@0 239 return cls(
michael@0 240 skipkeys=skipkeys, ensure_ascii=ensure_ascii,
michael@0 241 check_circular=check_circular, allow_nan=allow_nan, indent=indent,
michael@0 242 separators=separators, encoding=encoding, default=default,
michael@0 243 **kw).encode(obj)
michael@0 244
michael@0 245
michael@0 246 _default_decoder = JSONDecoder(encoding=None, object_hook=None)
michael@0 247
michael@0 248
michael@0 249 def load(fp, encoding=None, cls=None, object_hook=None, parse_float=None,
michael@0 250 parse_int=None, parse_constant=None, **kw):
michael@0 251 """
michael@0 252 Deserialize ``fp`` (a ``.read()``-supporting file-like object containing
michael@0 253 a JSON document) to a Python object.
michael@0 254
michael@0 255 If the contents of ``fp`` is encoded with an ASCII based encoding other
michael@0 256 than utf-8 (e.g. latin-1), then an appropriate ``encoding`` name must
michael@0 257 be specified. Encodings that are not ASCII based (such as UCS-2) are
michael@0 258 not allowed, and should be wrapped with
michael@0 259 ``codecs.getreader(fp)(encoding)``, or simply decoded to a ``unicode``
michael@0 260 object and passed to ``loads()``
michael@0 261
michael@0 262 ``object_hook`` is an optional function that will be called with the
michael@0 263 result of any object literal decode (a ``dict``). The return value of
michael@0 264 ``object_hook`` will be used instead of the ``dict``. This feature
michael@0 265 can be used to implement custom decoders (e.g. JSON-RPC class hinting).
michael@0 266
michael@0 267 To use a custom ``JSONDecoder`` subclass, specify it with the ``cls``
michael@0 268 kwarg.
michael@0 269 """
michael@0 270 return loads(fp.read(),
michael@0 271 encoding=encoding, cls=cls, object_hook=object_hook,
michael@0 272 parse_float=parse_float, parse_int=parse_int,
michael@0 273 parse_constant=parse_constant, **kw)
michael@0 274
michael@0 275
michael@0 276 def loads(s, encoding=None, cls=None, object_hook=None, parse_float=None,
michael@0 277 parse_int=None, parse_constant=None, **kw):
michael@0 278 """
michael@0 279 Deserialize ``s`` (a ``str`` or ``unicode`` instance containing a JSON
michael@0 280 document) to a Python object.
michael@0 281
michael@0 282 If ``s`` is a ``str`` instance and is encoded with an ASCII based encoding
michael@0 283 other than utf-8 (e.g. latin-1) then an appropriate ``encoding`` name
michael@0 284 must be specified. Encodings that are not ASCII based (such as UCS-2)
michael@0 285 are not allowed and should be decoded to ``unicode`` first.
michael@0 286
michael@0 287 ``object_hook`` is an optional function that will be called with the
michael@0 288 result of any object literal decode (a ``dict``). The return value of
michael@0 289 ``object_hook`` will be used instead of the ``dict``. This feature
michael@0 290 can be used to implement custom decoders (e.g. JSON-RPC class hinting).
michael@0 291
michael@0 292 ``parse_float``, if specified, will be called with the string
michael@0 293 of every JSON float to be decoded. By default this is equivalent to
michael@0 294 float(num_str). This can be used to use another datatype or parser
michael@0 295 for JSON floats (e.g. decimal.Decimal).
michael@0 296
michael@0 297 ``parse_int``, if specified, will be called with the string
michael@0 298 of every JSON int to be decoded. By default this is equivalent to
michael@0 299 int(num_str). This can be used to use another datatype or parser
michael@0 300 for JSON integers (e.g. float).
michael@0 301
michael@0 302 ``parse_constant``, if specified, will be called with one of the
michael@0 303 following strings: -Infinity, Infinity, NaN, null, true, false.
michael@0 304 This can be used to raise an exception if invalid JSON numbers
michael@0 305 are encountered.
michael@0 306
michael@0 307 To use a custom ``JSONDecoder`` subclass, specify it with the ``cls``
michael@0 308 kwarg.
michael@0 309 """
michael@0 310 if (cls is None and encoding is None and object_hook is None and
michael@0 311 parse_int is None and parse_float is None and
michael@0 312 parse_constant is None and not kw):
michael@0 313 return _default_decoder.decode(s)
michael@0 314 if cls is None:
michael@0 315 cls = JSONDecoder
michael@0 316 if object_hook is not None:
michael@0 317 kw['object_hook'] = object_hook
michael@0 318 if parse_float is not None:
michael@0 319 kw['parse_float'] = parse_float
michael@0 320 if parse_int is not None:
michael@0 321 kw['parse_int'] = parse_int
michael@0 322 if parse_constant is not None:
michael@0 323 kw['parse_constant'] = parse_constant
michael@0 324 return cls(encoding=encoding, **kw).decode(s)
michael@0 325
michael@0 326
michael@0 327 #
michael@0 328 # Compatibility cruft from other libraries
michael@0 329 #
michael@0 330
michael@0 331
michael@0 332 def decode(s):
michael@0 333 """
michael@0 334 demjson, python-cjson API compatibility hook. Use loads(s) instead.
michael@0 335 """
michael@0 336 import warnings
michael@0 337 warnings.warn("simplejson.loads(s) should be used instead of decode(s)",
michael@0 338 DeprecationWarning)
michael@0 339 return loads(s)
michael@0 340
michael@0 341
michael@0 342 def encode(obj):
michael@0 343 """
michael@0 344 demjson, python-cjson compatibility hook. Use dumps(s) instead.
michael@0 345 """
michael@0 346 import warnings
michael@0 347 warnings.warn("simplejson.dumps(s) should be used instead of encode(s)",
michael@0 348 DeprecationWarning)
michael@0 349 return dumps(obj)
michael@0 350
michael@0 351
michael@0 352 def read(s):
michael@0 353 """
michael@0 354 jsonlib, JsonUtils, python-json, json-py API compatibility hook.
michael@0 355 Use loads(s) instead.
michael@0 356 """
michael@0 357 import warnings
michael@0 358 warnings.warn("simplejson.loads(s) should be used instead of read(s)",
michael@0 359 DeprecationWarning)
michael@0 360 return loads(s)
michael@0 361
michael@0 362
michael@0 363 def write(obj):
michael@0 364 """
michael@0 365 jsonlib, JsonUtils, python-json, json-py API compatibility hook.
michael@0 366 Use dumps(s) instead.
michael@0 367 """
michael@0 368 import warnings
michael@0 369 warnings.warn("simplejson.dumps(s) should be used instead of write(s)",
michael@0 370 DeprecationWarning)
michael@0 371 return dumps(obj)
michael@0 372
michael@0 373
michael@0 374 if __name__ == '__main__':
michael@0 375 import simplejson.tool
michael@0 376 simplejson.tool.main()

mercurial