1
"""Implementation of JSONEncoder
6
from _json import encode_basestring_ascii as c_encode_basestring_ascii
8
c_encode_basestring_ascii = None
10
from _json import make_encoder as c_make_encoder
14
ESCAPE = re.compile(r'[\x00-\x1f\\"\b\f\n\r\t]')
15
ESCAPE_ASCII = re.compile(r'([\\"]|[^\ -~])')
16
HAS_UTF8 = re.compile(b'[\x80-\xff]')
27
ESCAPE_DCT.setdefault(chr(i), '\\u{0:04x}'.format(i))
28
#ESCAPE_DCT.setdefault(chr(i), '\\u%04x' % (i,))
30
INFINITY = float('inf')
33
def encode_basestring(s):
34
"""Return a JSON representation of a Python string
38
return ESCAPE_DCT[match.group(0)]
39
return '"' + ESCAPE.sub(replace, s) + '"'
42
def py_encode_basestring_ascii(s):
43
"""Return an ASCII-only JSON representation of a Python string
53
return '\\u{0:04x}'.format(n)
54
#return '\\u%04x' % (n,)
58
s1 = 0xd800 | ((n >> 10) & 0x3ff)
59
s2 = 0xdc00 | (n & 0x3ff)
60
return '\\u{0:04x}\\u{1:04x}'.format(s1, s2)
61
return '"' + ESCAPE_ASCII.sub(replace, s) + '"'
64
encode_basestring_ascii = (
65
c_encode_basestring_ascii or py_encode_basestring_ascii)
67
class JSONEncoder(object):
68
"""Extensible JSON <http://json.org> encoder for Python data structures.
70
Supports the following objects and types by default:
72
+-------------------+---------------+
74
+===================+===============+
76
+-------------------+---------------+
77
| list, tuple | array |
78
+-------------------+---------------+
80
+-------------------+---------------+
81
| int, float | number |
82
+-------------------+---------------+
84
+-------------------+---------------+
86
+-------------------+---------------+
88
+-------------------+---------------+
90
To extend this to recognize other objects, subclass and implement a
91
``.default()`` method with another method that returns a serializable
92
object for ``o`` if possible, otherwise it should call the superclass
93
implementation (to raise ``TypeError``).
98
def __init__(self, skipkeys=False, ensure_ascii=True,
99
check_circular=True, allow_nan=True, sort_keys=False,
100
indent=None, separators=None, default=None):
101
"""Constructor for JSONEncoder, with sensible defaults.
103
If skipkeys is false, then it is a TypeError to attempt
104
encoding of keys that are not str, int, float or None. If
105
skipkeys is True, such items are simply skipped.
107
If ensure_ascii is true, the output is guaranteed to be str
108
objects with all incoming non-ASCII characters escaped. If
109
ensure_ascii is false, the output can contain non-ASCII characters.
111
If check_circular is true, then lists, dicts, and custom encoded
112
objects will be checked for circular references during encoding to
113
prevent an infinite recursion (which would cause an OverflowError).
114
Otherwise, no such check takes place.
116
If allow_nan is true, then NaN, Infinity, and -Infinity will be
117
encoded as such. This behavior is not JSON specification compliant,
118
but is consistent with most JavaScript based encoders and decoders.
119
Otherwise, it will be a ValueError to encode such floats.
121
If sort_keys is true, then the output of dictionaries will be
122
sorted by key; this is useful for regression tests to ensure
123
that JSON serializations can be compared on a day-to-day basis.
125
If indent is a non-negative integer, then JSON array
126
elements and object members will be pretty-printed with that
127
indent level. An indent level of 0 will only insert newlines.
128
None is the most compact representation.
130
If specified, separators should be an (item_separator, key_separator)
131
tuple. The default is (', ', ': ') if *indent* is ``None`` and
132
(',', ': ') otherwise. To get the most compact JSON representation,
133
you should specify (',', ':') to eliminate whitespace.
135
If specified, default is a function that gets called for objects
136
that can't otherwise be serialized. It should return a JSON encodable
137
version of the object or raise a ``TypeError``.
141
self.skipkeys = skipkeys
142
self.ensure_ascii = ensure_ascii
143
self.check_circular = check_circular
144
self.allow_nan = allow_nan
145
self.sort_keys = sort_keys
147
if separators is not None:
148
self.item_separator, self.key_separator = separators
149
elif indent is not None:
150
self.item_separator = ','
151
if default is not None:
152
self.default = default
154
def default(self, o):
155
"""Implement this method in a subclass such that it returns
156
a serializable object for ``o``, or calls the base implementation
157
(to raise a ``TypeError``).
159
For example, to support arbitrary iterators, you could
160
implement default like this::
162
def default(self, o):
168
return list(iterable)
169
# Let the base class default method raise the TypeError
170
return JSONEncoder.default(self, o)
173
raise TypeError(repr(o) + " is not JSON serializable")
176
"""Return a JSON string representation of a Python data structure.
178
>>> from json.encoder import JSONEncoder
179
>>> JSONEncoder().encode({"foo": ["bar", "baz"]})
180
'{"foo": ["bar", "baz"]}'
183
# This is for extremely simple cases and benchmarks.
184
if isinstance(o, str):
185
if self.ensure_ascii:
186
return encode_basestring_ascii(o)
188
return encode_basestring(o)
189
# This doesn't pass the iterator directly to ''.join() because the
190
# exceptions aren't as detailed. The list call should be roughly
191
# equivalent to the PySequence_Fast that ''.join() would do.
192
chunks = self.iterencode(o, _one_shot=True)
193
if not isinstance(chunks, (list, tuple)):
194
chunks = list(chunks)
195
return ''.join(chunks)
197
def iterencode(self, o, _one_shot=False):
198
"""Encode the given object and yield each string
199
representation as available.
203
for chunk in JSONEncoder().iterencode(bigobject):
204
mysocket.write(chunk)
207
if self.check_circular:
211
if self.ensure_ascii:
212
_encoder = encode_basestring_ascii
214
_encoder = encode_basestring
216
def floatstr(o, allow_nan=self.allow_nan,
217
_repr=FLOAT_REPR, _inf=INFINITY, _neginf=-INFINITY):
218
# Check for specials. Note that this type of test is processor
219
# and/or platform-specific, so do tests which don't depend on the
233
"Out of range float values are not JSON compliant: " +
239
if (_one_shot and c_make_encoder is not None
240
and self.indent is None):
241
_iterencode = c_make_encoder(
242
markers, self.default, _encoder, self.indent,
243
self.key_separator, self.item_separator, self.sort_keys,
244
self.skipkeys, self.allow_nan)
246
_iterencode = _make_iterencode(
247
markers, self.default, _encoder, self.indent, floatstr,
248
self.key_separator, self.item_separator, self.sort_keys,
249
self.skipkeys, _one_shot)
250
return _iterencode(o, 0)
252
def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
253
_key_separator, _item_separator, _sort_keys, _skipkeys, _one_shot,
254
## HACK: hand-optimized bytecode; turn globals into locals
255
ValueError=ValueError,
260
isinstance=isinstance,
266
if _indent is not None and not isinstance(_indent, str):
267
_indent = ' ' * _indent
269
def _iterencode_list(lst, _current_indent_level):
273
if markers is not None:
275
if markerid in markers:
276
raise ValueError("Circular reference detected")
277
markers[markerid] = lst
279
if _indent is not None:
280
_current_indent_level += 1
281
newline_indent = '\n' + _indent * _current_indent_level
282
separator = _item_separator + newline_indent
283
buf += newline_indent
285
newline_indent = None
286
separator = _item_separator
293
if isinstance(value, str):
294
yield buf + _encoder(value)
301
elif isinstance(value, int):
302
# Subclasses of int/float may override __str__, but we still
303
# want to encode them as integers/floats in JSON. One example
304
# within the standard library is IntEnum.
305
yield buf + str(int(value))
306
elif isinstance(value, float):
307
# see comment above for int
308
yield buf + _floatstr(float(value))
311
if isinstance(value, (list, tuple)):
312
chunks = _iterencode_list(value, _current_indent_level)
313
elif isinstance(value, dict):
314
chunks = _iterencode_dict(value, _current_indent_level)
316
chunks = _iterencode(value, _current_indent_level)
318
if newline_indent is not None:
319
_current_indent_level -= 1
320
yield '\n' + _indent * _current_indent_level
322
if markers is not None:
323
del markers[markerid]
325
def _iterencode_dict(dct, _current_indent_level):
329
if markers is not None:
331
if markerid in markers:
332
raise ValueError("Circular reference detected")
333
markers[markerid] = dct
335
if _indent is not None:
336
_current_indent_level += 1
337
newline_indent = '\n' + _indent * _current_indent_level
338
item_separator = _item_separator + newline_indent
341
newline_indent = None
342
item_separator = _item_separator
345
items = sorted(dct.items(), key=lambda kv: kv[0])
348
for key, value in items:
349
if isinstance(key, str):
351
# JavaScript is weakly typed for these, so it makes sense to
352
# also allow them. Many encoders seem to do something like this.
353
elif isinstance(key, float):
354
# see comment for int/float in _make_iterencode
355
key = _floatstr(float(key))
362
elif isinstance(key, int):
363
# see comment for int/float in _make_iterencode
368
raise TypeError("key " + repr(key) + " is not a string")
375
if isinstance(value, str):
376
yield _encoder(value)
383
elif isinstance(value, int):
384
# see comment for int/float in _make_iterencode
385
yield str(int(value))
386
elif isinstance(value, float):
387
# see comment for int/float in _make_iterencode
388
yield _floatstr(float(value))
390
if isinstance(value, (list, tuple)):
391
chunks = _iterencode_list(value, _current_indent_level)
392
elif isinstance(value, dict):
393
chunks = _iterencode_dict(value, _current_indent_level)
395
chunks = _iterencode(value, _current_indent_level)
397
if newline_indent is not None:
398
_current_indent_level -= 1
399
yield '\n' + _indent * _current_indent_level
401
if markers is not None:
402
del markers[markerid]
404
def _iterencode(o, _current_indent_level):
405
if isinstance(o, str):
413
elif isinstance(o, int):
414
# see comment for int/float in _make_iterencode
416
elif isinstance(o, float):
417
# see comment for int/float in _make_iterencode
418
yield _floatstr(float(o))
419
elif isinstance(o, (list, tuple)):
420
yield from _iterencode_list(o, _current_indent_level)
421
elif isinstance(o, dict):
422
yield from _iterencode_dict(o, _current_indent_level)
424
if markers is not None:
426
if markerid in markers:
427
raise ValueError("Circular reference detected")
428
markers[markerid] = o
430
yield from _iterencode(o, _current_indent_level)
431
if markers is not None:
432
del markers[markerid]