~clint-fewbar/+junk/chromium-depot-tools

« back to all changes in this revision

Viewing changes to src/depot_tools/third_party/simplejson/__init__.py

  • Committer: Clint Byrum
  • Date: 2010-11-05 05:15:19 UTC
  • Revision ID: clint@ubuntu.com-20101105051519-u1zg447kmycmw89i
Initial release for use until chromium-browser exports this as a 
binary package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
r"""JSON (JavaScript Object Notation) <http://json.org> is a subset of
 
2
JavaScript syntax (ECMA-262 3rd edition) used as a lightweight data
 
3
interchange format.
 
4
 
 
5
:mod:`simplejson` exposes an API familiar to users of the standard library
 
6
:mod:`marshal` and :mod:`pickle` modules. It is the externally maintained
 
7
version of the :mod:`json` library contained in Python 2.6, but maintains
 
8
compatibility with Python 2.4 and Python 2.5 and (currently) has
 
9
significant performance advantages, even without using the optional C
 
10
extension for speedups.
 
11
 
 
12
Encoding basic Python object hierarchies::
 
13
 
 
14
    >>> import simplejson as json
 
15
    >>> json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}])
 
16
    '["foo", {"bar": ["baz", null, 1.0, 2]}]'
 
17
    >>> print json.dumps("\"foo\bar")
 
18
    "\"foo\bar"
 
19
    >>> print json.dumps(u'\u1234')
 
20
    "\u1234"
 
21
    >>> print json.dumps('\\')
 
22
    "\\"
 
23
    >>> print json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True)
 
24
    {"a": 0, "b": 0, "c": 0}
 
25
    >>> from StringIO import StringIO
 
26
    >>> io = StringIO()
 
27
    >>> json.dump(['streaming API'], io)
 
28
    >>> io.getvalue()
 
29
    '["streaming API"]'
 
30
 
 
31
Compact encoding::
 
32
 
 
33
    >>> import simplejson as json
 
34
    >>> json.dumps([1,2,3,{'4': 5, '6': 7}], separators=(',',':'))
 
35
    '[1,2,3,{"4":5,"6":7}]'
 
36
 
 
37
Pretty printing::
 
38
 
 
39
    >>> import simplejson as json
 
40
    >>> s = json.dumps({'4': 5, '6': 7}, sort_keys=True, indent='    ')
 
41
    >>> print '\n'.join([l.rstrip() for l in  s.splitlines()])
 
42
    {
 
43
        "4": 5,
 
44
        "6": 7
 
45
    }
 
46
 
 
47
Decoding JSON::
 
48
 
 
49
    >>> import simplejson as json
 
50
    >>> obj = [u'foo', {u'bar': [u'baz', None, 1.0, 2]}]
 
51
    >>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]') == obj
 
52
    True
 
53
    >>> json.loads('"\\"foo\\bar"') == u'"foo\x08ar'
 
54
    True
 
55
    >>> from StringIO import StringIO
 
56
    >>> io = StringIO('["streaming API"]')
 
57
    >>> json.load(io)[0] == 'streaming API'
 
58
    True
 
59
 
 
60
Specializing JSON object decoding::
 
61
 
 
62
    >>> import simplejson as json
 
63
    >>> def as_complex(dct):
 
64
    ...     if '__complex__' in dct:
 
65
    ...         return complex(dct['real'], dct['imag'])
 
66
    ...     return dct
 
67
    ...
 
68
    >>> json.loads('{"__complex__": true, "real": 1, "imag": 2}',
 
69
    ...     object_hook=as_complex)
 
70
    (1+2j)
 
71
    >>> from decimal import Decimal
 
72
    >>> json.loads('1.1', parse_float=Decimal) == Decimal('1.1')
 
73
    True
 
74
 
 
75
Specializing JSON object encoding::
 
76
 
 
77
    >>> import simplejson as json
 
78
    >>> def encode_complex(obj):
 
79
    ...     if isinstance(obj, complex):
 
80
    ...         return [obj.real, obj.imag]
 
81
    ...     raise TypeError(repr(o) + " is not JSON serializable")
 
82
    ...
 
83
    >>> json.dumps(2 + 1j, default=encode_complex)
 
84
    '[2.0, 1.0]'
 
85
    >>> json.JSONEncoder(default=encode_complex).encode(2 + 1j)
 
86
    '[2.0, 1.0]'
 
87
    >>> ''.join(json.JSONEncoder(default=encode_complex).iterencode(2 + 1j))
 
88
    '[2.0, 1.0]'
 
89
 
 
90
 
 
91
Using simplejson.tool from the shell to validate and pretty-print::
 
92
 
 
93
    $ echo '{"json":"obj"}' | python -m simplejson.tool
 
94
    {
 
95
        "json": "obj"
 
96
    }
 
97
    $ echo '{ 1.2:3.4}' | python -m simplejson.tool
 
98
    Expecting property name: line 1 column 2 (char 2)
 
99
"""
 
100
__version__ = '2.1.0rc3'
 
101
__all__ = [
 
102
    'dump', 'dumps', 'load', 'loads',
 
103
    'JSONDecoder', 'JSONDecodeError', 'JSONEncoder',
 
104
    'OrderedDict',
 
105
]
 
106
 
 
107
__author__ = 'Bob Ippolito <bob@redivi.com>'
 
108
 
 
109
from decimal import Decimal
 
110
 
 
111
from decoder import JSONDecoder, JSONDecodeError
 
112
from encoder import JSONEncoder
 
113
def _import_OrderedDict():
 
114
    import collections
 
115
    try:
 
116
        return collections.OrderedDict
 
117
    except AttributeError:
 
118
        import ordered_dict
 
119
        return ordered_dict.OrderedDict
 
120
OrderedDict = _import_OrderedDict()
 
121
 
 
122
def _import_c_make_encoder():
 
123
    try:
 
124
        from simplejson._speedups import make_encoder
 
125
        return make_encoder
 
126
    except ImportError:
 
127
        return None
 
128
 
 
129
_default_encoder = JSONEncoder(
 
130
    skipkeys=False,
 
131
    ensure_ascii=True,
 
132
    check_circular=True,
 
133
    allow_nan=True,
 
134
    indent=None,
 
135
    separators=None,
 
136
    encoding='utf-8',
 
137
    default=None,
 
138
    use_decimal=False,
 
139
)
 
140
 
 
141
def dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True,
 
142
        allow_nan=True, cls=None, indent=None, separators=None,
 
143
        encoding='utf-8', default=None, use_decimal=False, **kw):
 
144
    """Serialize ``obj`` as a JSON formatted stream to ``fp`` (a
 
145
    ``.write()``-supporting file-like object).
 
146
 
 
147
    If ``skipkeys`` is true then ``dict`` keys that are not basic types
 
148
    (``str``, ``unicode``, ``int``, ``long``, ``float``, ``bool``, ``None``)
 
149
    will be skipped instead of raising a ``TypeError``.
 
150
 
 
151
    If ``ensure_ascii`` is false, then the some chunks written to ``fp``
 
152
    may be ``unicode`` instances, subject to normal Python ``str`` to
 
153
    ``unicode`` coercion rules. Unless ``fp.write()`` explicitly
 
154
    understands ``unicode`` (as in ``codecs.getwriter()``) this is likely
 
155
    to cause an error.
 
156
 
 
157
    If ``check_circular`` is false, then the circular reference check
 
158
    for container types will be skipped and a circular reference will
 
159
    result in an ``OverflowError`` (or worse).
 
160
 
 
161
    If ``allow_nan`` is false, then it will be a ``ValueError`` to
 
162
    serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``)
 
163
    in strict compliance of the JSON specification, instead of using the
 
164
    JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``).
 
165
 
 
166
    If *indent* is a string, then JSON array elements and object members
 
167
    will be pretty-printed with a newline followed by that string repeated
 
168
    for each level of nesting. ``None`` (the default) selects the most compact
 
169
    representation without any newlines. For backwards compatibility with
 
170
    versions of simplejson earlier than 2.1.0, an integer is also accepted
 
171
    and is converted to a string with that many spaces.
 
172
 
 
173
    If ``separators`` is an ``(item_separator, dict_separator)`` tuple
 
174
    then it will be used instead of the default ``(', ', ': ')`` separators.
 
175
    ``(',', ':')`` is the most compact JSON representation.
 
176
 
 
177
    ``encoding`` is the character encoding for str instances, default is UTF-8.
 
178
 
 
179
    ``default(obj)`` is a function that should return a serializable version
 
180
    of obj or raise TypeError. The default simply raises TypeError.
 
181
 
 
182
    If *use_decimal* is true (default: ``False``) then decimal.Decimal
 
183
    will be natively serialized to JSON with full precision.
 
184
 
 
185
    To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the
 
186
    ``.default()`` method to serialize additional types), specify it with
 
187
    the ``cls`` kwarg.
 
188
 
 
189
    """
 
190
    # cached encoder
 
191
    if (not skipkeys and ensure_ascii and
 
192
        check_circular and allow_nan and
 
193
        cls is None and indent is None and separators is None and
 
194
        encoding == 'utf-8' and default is None and not kw):
 
195
        iterable = _default_encoder.iterencode(obj)
 
196
    else:
 
197
        if cls is None:
 
198
            cls = JSONEncoder
 
199
        iterable = cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii,
 
200
            check_circular=check_circular, allow_nan=allow_nan, indent=indent,
 
201
            separators=separators, encoding=encoding,
 
202
            default=default, use_decimal=use_decimal, **kw).iterencode(obj)
 
203
    # could accelerate with writelines in some versions of Python, at
 
204
    # a debuggability cost
 
205
    for chunk in iterable:
 
206
        fp.write(chunk)
 
207
 
 
208
 
 
209
def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True,
 
210
        allow_nan=True, cls=None, indent=None, separators=None,
 
211
        encoding='utf-8', default=None, use_decimal=False, **kw):
 
212
    """Serialize ``obj`` to a JSON formatted ``str``.
 
213
 
 
214
    If ``skipkeys`` is false then ``dict`` keys that are not basic types
 
215
    (``str``, ``unicode``, ``int``, ``long``, ``float``, ``bool``, ``None``)
 
216
    will be skipped instead of raising a ``TypeError``.
 
217
 
 
218
    If ``ensure_ascii`` is false, then the return value will be a
 
219
    ``unicode`` instance subject to normal Python ``str`` to ``unicode``
 
220
    coercion rules instead of being escaped to an ASCII ``str``.
 
221
 
 
222
    If ``check_circular`` is false, then the circular reference check
 
223
    for container types will be skipped and a circular reference will
 
224
    result in an ``OverflowError`` (or worse).
 
225
 
 
226
    If ``allow_nan`` is false, then it will be a ``ValueError`` to
 
227
    serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in
 
228
    strict compliance of the JSON specification, instead of using the
 
229
    JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``).
 
230
 
 
231
    If ``indent`` is a string, then JSON array elements and object members
 
232
    will be pretty-printed with a newline followed by that string repeated
 
233
    for each level of nesting. ``None`` (the default) selects the most compact
 
234
    representation without any newlines. For backwards compatibility with
 
235
    versions of simplejson earlier than 2.1.0, an integer is also accepted
 
236
    and is converted to a string with that many spaces.
 
237
 
 
238
    If ``separators`` is an ``(item_separator, dict_separator)`` tuple
 
239
    then it will be used instead of the default ``(', ', ': ')`` separators.
 
240
    ``(',', ':')`` is the most compact JSON representation.
 
241
 
 
242
    ``encoding`` is the character encoding for str instances, default is UTF-8.
 
243
 
 
244
    ``default(obj)`` is a function that should return a serializable version
 
245
    of obj or raise TypeError. The default simply raises TypeError.
 
246
 
 
247
    If *use_decimal* is true (default: ``False``) then decimal.Decimal
 
248
    will be natively serialized to JSON with full precision.
 
249
 
 
250
    To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the
 
251
    ``.default()`` method to serialize additional types), specify it with
 
252
    the ``cls`` kwarg.
 
253
 
 
254
    """
 
255
    # cached encoder
 
256
    if (not skipkeys and ensure_ascii and
 
257
        check_circular and allow_nan and
 
258
        cls is None and indent is None and separators is None and
 
259
        encoding == 'utf-8' and default is None and not use_decimal
 
260
        and not kw):
 
261
        return _default_encoder.encode(obj)
 
262
    if cls is None:
 
263
        cls = JSONEncoder
 
264
    return cls(
 
265
        skipkeys=skipkeys, ensure_ascii=ensure_ascii,
 
266
        check_circular=check_circular, allow_nan=allow_nan, indent=indent,
 
267
        separators=separators, encoding=encoding, default=default,
 
268
        use_decimal=use_decimal, **kw).encode(obj)
 
269
 
 
270
 
 
271
_default_decoder = JSONDecoder(encoding=None, object_hook=None,
 
272
                               object_pairs_hook=None)
 
273
 
 
274
 
 
275
def load(fp, encoding=None, cls=None, object_hook=None, parse_float=None,
 
276
        parse_int=None, parse_constant=None, object_pairs_hook=None,
 
277
        use_decimal=False, **kw):
 
278
    """Deserialize ``fp`` (a ``.read()``-supporting file-like object containing
 
279
    a JSON document) to a Python object.
 
280
 
 
281
    *encoding* determines the encoding used to interpret any
 
282
    :class:`str` objects decoded by this instance (``'utf-8'`` by
 
283
    default).  It has no effect when decoding :class:`unicode` objects.
 
284
 
 
285
    Note that currently only encodings that are a superset of ASCII work,
 
286
    strings of other encodings should be passed in as :class:`unicode`.
 
287
 
 
288
    *object_hook*, if specified, will be called with the result of every
 
289
    JSON object decoded and its return value will be used in place of the
 
290
    given :class:`dict`.  This can be used to provide custom
 
291
    deserializations (e.g. to support JSON-RPC class hinting).
 
292
 
 
293
    *object_pairs_hook* is an optional function that will be called with
 
294
    the result of any object literal decode with an ordered list of pairs.
 
295
    The return value of *object_pairs_hook* will be used instead of the
 
296
    :class:`dict`.  This feature can be used to implement custom decoders
 
297
    that rely on the order that the key and value pairs are decoded (for
 
298
    example, :func:`collections.OrderedDict` will remember the order of
 
299
    insertion). If *object_hook* is also defined, the *object_pairs_hook*
 
300
    takes priority.
 
301
 
 
302
    *parse_float*, if specified, will be called with the string of every
 
303
    JSON float to be decoded.  By default, this is equivalent to
 
304
    ``float(num_str)``. This can be used to use another datatype or parser
 
305
    for JSON floats (e.g. :class:`decimal.Decimal`).
 
306
 
 
307
    *parse_int*, if specified, will be called with the string of every
 
308
    JSON int to be decoded.  By default, this is equivalent to
 
309
    ``int(num_str)``.  This can be used to use another datatype or parser
 
310
    for JSON integers (e.g. :class:`float`).
 
311
 
 
312
    *parse_constant*, if specified, will be called with one of the
 
313
    following strings: ``'-Infinity'``, ``'Infinity'``, ``'NaN'``.  This
 
314
    can be used to raise an exception if invalid JSON numbers are
 
315
    encountered.
 
316
 
 
317
    If *use_decimal* is true (default: ``False``) then it implies
 
318
    parse_float=decimal.Decimal for parity with ``dump``.
 
319
 
 
320
    To use a custom ``JSONDecoder`` subclass, specify it with the ``cls``
 
321
    kwarg.
 
322
 
 
323
    """
 
324
    return loads(fp.read(),
 
325
        encoding=encoding, cls=cls, object_hook=object_hook,
 
326
        parse_float=parse_float, parse_int=parse_int,
 
327
        parse_constant=parse_constant, object_pairs_hook=object_pairs_hook,
 
328
        use_decimal=use_decimal, **kw)
 
329
 
 
330
 
 
331
def loads(s, encoding=None, cls=None, object_hook=None, parse_float=None,
 
332
        parse_int=None, parse_constant=None, object_pairs_hook=None,
 
333
        use_decimal=False, **kw):
 
334
    """Deserialize ``s`` (a ``str`` or ``unicode`` instance containing a JSON
 
335
    document) to a Python object.
 
336
 
 
337
    *encoding* determines the encoding used to interpret any
 
338
    :class:`str` objects decoded by this instance (``'utf-8'`` by
 
339
    default).  It has no effect when decoding :class:`unicode` objects.
 
340
 
 
341
    Note that currently only encodings that are a superset of ASCII work,
 
342
    strings of other encodings should be passed in as :class:`unicode`.
 
343
 
 
344
    *object_hook*, if specified, will be called with the result of every
 
345
    JSON object decoded and its return value will be used in place of the
 
346
    given :class:`dict`.  This can be used to provide custom
 
347
    deserializations (e.g. to support JSON-RPC class hinting).
 
348
 
 
349
    *object_pairs_hook* is an optional function that will be called with
 
350
    the result of any object literal decode with an ordered list of pairs.
 
351
    The return value of *object_pairs_hook* will be used instead of the
 
352
    :class:`dict`.  This feature can be used to implement custom decoders
 
353
    that rely on the order that the key and value pairs are decoded (for
 
354
    example, :func:`collections.OrderedDict` will remember the order of
 
355
    insertion). If *object_hook* is also defined, the *object_pairs_hook*
 
356
    takes priority.
 
357
 
 
358
    *parse_float*, if specified, will be called with the string of every
 
359
    JSON float to be decoded.  By default, this is equivalent to
 
360
    ``float(num_str)``. This can be used to use another datatype or parser
 
361
    for JSON floats (e.g. :class:`decimal.Decimal`).
 
362
 
 
363
    *parse_int*, if specified, will be called with the string of every
 
364
    JSON int to be decoded.  By default, this is equivalent to
 
365
    ``int(num_str)``.  This can be used to use another datatype or parser
 
366
    for JSON integers (e.g. :class:`float`).
 
367
 
 
368
    *parse_constant*, if specified, will be called with one of the
 
369
    following strings: ``'-Infinity'``, ``'Infinity'``, ``'NaN'``.  This
 
370
    can be used to raise an exception if invalid JSON numbers are
 
371
    encountered.
 
372
 
 
373
    If *use_decimal* is true (default: ``False``) then it implies
 
374
    parse_float=decimal.Decimal for parity with ``dump``.
 
375
 
 
376
    To use a custom ``JSONDecoder`` subclass, specify it with the ``cls``
 
377
    kwarg.
 
378
 
 
379
    """
 
380
    if (cls is None and encoding is None and object_hook is None and
 
381
            parse_int is None and parse_float is None and
 
382
            parse_constant is None and object_pairs_hook is None
 
383
            and not use_decimal and not kw):
 
384
        return _default_decoder.decode(s)
 
385
    if cls is None:
 
386
        cls = JSONDecoder
 
387
    if object_hook is not None:
 
388
        kw['object_hook'] = object_hook
 
389
    if object_pairs_hook is not None:
 
390
        kw['object_pairs_hook'] = object_pairs_hook
 
391
    if parse_float is not None:
 
392
        kw['parse_float'] = parse_float
 
393
    if parse_int is not None:
 
394
        kw['parse_int'] = parse_int
 
395
    if parse_constant is not None:
 
396
        kw['parse_constant'] = parse_constant
 
397
    if use_decimal:
 
398
        if parse_float is not None:
 
399
            raise TypeError("use_decimal=True implies parse_float=Decimal")
 
400
        kw['parse_float'] = Decimal
 
401
    return cls(encoding=encoding, **kw).decode(s)
 
402
 
 
403
 
 
404
def _toggle_speedups(enabled):
 
405
    import simplejson.decoder as dec
 
406
    import simplejson.encoder as enc
 
407
    import simplejson.scanner as scan
 
408
    c_make_encoder = _import_c_make_encoder()
 
409
    if enabled:
 
410
        dec.scanstring = dec.c_scanstring or dec.py_scanstring
 
411
        enc.c_make_encoder = c_make_encoder
 
412
        enc.encode_basestring_ascii = (enc.c_encode_basestring_ascii or 
 
413
            enc.py_encode_basestring_ascii)
 
414
        scan.make_scanner = scan.c_make_scanner or scan.py_make_scanner
 
415
    else:
 
416
        dec.scanstring = dec.py_scanstring
 
417
        enc.c_make_encoder = None
 
418
        enc.encode_basestring_ascii = enc.py_encode_basestring_ascii
 
419
        scan.make_scanner = scan.py_make_scanner
 
420
    dec.make_scanner = scan.make_scanner
 
421
    global _default_decoder
 
422
    _default_decoder = JSONDecoder(
 
423
        encoding=None,
 
424
        object_hook=None,
 
425
        object_pairs_hook=None,
 
426
    )
 
427
    global _default_encoder
 
428
    _default_encoder = JSONEncoder(
 
429
       skipkeys=False,
 
430
       ensure_ascii=True,
 
431
       check_circular=True,
 
432
       allow_nan=True,
 
433
       indent=None,
 
434
       separators=None,
 
435
       encoding='utf-8',
 
436
       default=None,
 
437
   )