1ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh"""Implementation of JSONEncoder 2ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh""" 3ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehimport re 4ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 5ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehtry: 6ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh from _json import encode_basestring_ascii as c_encode_basestring_ascii 7ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehexcept ImportError: 8ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh c_encode_basestring_ascii = None 9ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehtry: 10ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh from _json import make_encoder as c_make_encoder 11ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehexcept ImportError: 12ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh c_make_encoder = None 13ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 14ffab958fd8d42ed7227d83007350e61555a1fa36Andrew HsiehESCAPE = re.compile(r'[\x00-\x1f\\"\b\f\n\r\t]') 15ffab958fd8d42ed7227d83007350e61555a1fa36Andrew HsiehESCAPE_ASCII = re.compile(r'([\\"]|[^\ -~])') 16ffab958fd8d42ed7227d83007350e61555a1fa36Andrew HsiehHAS_UTF8 = re.compile(r'[\x80-\xff]') 17ffab958fd8d42ed7227d83007350e61555a1fa36Andrew HsiehESCAPE_DCT = { 18ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh '\\': '\\\\', 19ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh '"': '\\"', 20ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh '\b': '\\b', 21ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh '\f': '\\f', 22ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh '\n': '\\n', 23ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh '\r': '\\r', 24ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh '\t': '\\t', 25ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh} 26ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehfor i in range(0x20): 27ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh ESCAPE_DCT.setdefault(chr(i), '\\u{0:04x}'.format(i)) 28ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh #ESCAPE_DCT.setdefault(chr(i), '\\u%04x' % (i,)) 29ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 30ffab958fd8d42ed7227d83007350e61555a1fa36Andrew HsiehINFINITY = float('inf') 31ffab958fd8d42ed7227d83007350e61555a1fa36Andrew HsiehFLOAT_REPR = repr 32ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 33ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef encode_basestring(s): 34ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh """Return a JSON representation of a Python string 35ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 36ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh """ 37ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def replace(match): 38ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return ESCAPE_DCT[match.group(0)] 39ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return '"' + ESCAPE.sub(replace, s) + '"' 40ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 41ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 42ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef py_encode_basestring_ascii(s): 43ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh """Return an ASCII-only JSON representation of a Python string 44ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 45ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh """ 46ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if isinstance(s, str) and HAS_UTF8.search(s) is not None: 47ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh s = s.decode('utf-8') 48ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def replace(match): 49ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh s = match.group(0) 50ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh try: 51ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return ESCAPE_DCT[s] 52ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh except KeyError: 53ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh n = ord(s) 54ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if n < 0x10000: 55ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return '\\u{0:04x}'.format(n) 56ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh #return '\\u%04x' % (n,) 57ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh else: 58ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # surrogate pair 59ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh n -= 0x10000 60ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh s1 = 0xd800 | ((n >> 10) & 0x3ff) 61ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh s2 = 0xdc00 | (n & 0x3ff) 62ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return '\\u{0:04x}\\u{1:04x}'.format(s1, s2) 63ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh #return '\\u%04x\\u%04x' % (s1, s2) 64ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return '"' + str(ESCAPE_ASCII.sub(replace, s)) + '"' 65ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 66ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 67ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehencode_basestring_ascii = ( 68ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh c_encode_basestring_ascii or py_encode_basestring_ascii) 69ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 70ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehclass JSONEncoder(object): 71ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh """Extensible JSON <http://json.org> encoder for Python data structures. 72ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 73ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh Supports the following objects and types by default: 74ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 75ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh +-------------------+---------------+ 76ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh | Python | JSON | 77ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh +===================+===============+ 78ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh | dict | object | 79ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh +-------------------+---------------+ 80ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh | list, tuple | array | 81ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh +-------------------+---------------+ 82ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh | str, unicode | string | 83ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh +-------------------+---------------+ 84ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh | int, long, float | number | 85ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh +-------------------+---------------+ 86ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh | True | true | 87ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh +-------------------+---------------+ 88ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh | False | false | 89ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh +-------------------+---------------+ 90ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh | None | null | 91ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh +-------------------+---------------+ 92ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 93ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh To extend this to recognize other objects, subclass and implement a 94ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh ``.default()`` method with another method that returns a serializable 95ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh object for ``o`` if possible, otherwise it should call the superclass 96ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh implementation (to raise ``TypeError``). 97ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 98ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh """ 99ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh item_separator = ', ' 100ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh key_separator = ': ' 101ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def __init__(self, skipkeys=False, ensure_ascii=True, 102ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh check_circular=True, allow_nan=True, sort_keys=False, 103ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh indent=None, separators=None, encoding='utf-8', default=None): 104ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh """Constructor for JSONEncoder, with sensible defaults. 105ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 106ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh If skipkeys is false, then it is a TypeError to attempt 107ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh encoding of keys that are not str, int, long, float or None. If 108ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh skipkeys is True, such items are simply skipped. 109ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 110ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh If *ensure_ascii* is true (the default), all non-ASCII 111ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh characters in the output are escaped with \uXXXX sequences, 112ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh and the results are str instances consisting of ASCII 113ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh characters only. If ensure_ascii is False, a result may be a 114ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh unicode instance. This usually happens if the input contains 115ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh unicode strings or the *encoding* parameter is used. 116ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 117ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh If check_circular is true, then lists, dicts, and custom encoded 118ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh objects will be checked for circular references during encoding to 119ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh prevent an infinite recursion (which would cause an OverflowError). 120ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh Otherwise, no such check takes place. 121ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 122ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh If allow_nan is true, then NaN, Infinity, and -Infinity will be 123ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh encoded as such. This behavior is not JSON specification compliant, 124ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh but is consistent with most JavaScript based encoders and decoders. 125ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh Otherwise, it will be a ValueError to encode such floats. 126ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 127ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh If sort_keys is true, then the output of dictionaries will be 128ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh sorted by key; this is useful for regression tests to ensure 129ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh that JSON serializations can be compared on a day-to-day basis. 130ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 131ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh If indent is a non-negative integer, then JSON array 132ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh elements and object members will be pretty-printed with that 133ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh indent level. An indent level of 0 will only insert newlines. 134ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh None is the most compact representation. Since the default 135ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh item separator is ', ', the output might include trailing 136ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh whitespace when indent is specified. You can use 137ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh separators=(',', ': ') to avoid this. 138ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 139ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh If specified, separators should be a (item_separator, key_separator) 140ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh tuple. The default is (', ', ': '). To get the most compact JSON 141ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh representation you should specify (',', ':') to eliminate whitespace. 142ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 143ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh If specified, default is a function that gets called for objects 144ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh that can't otherwise be serialized. It should return a JSON encodable 145ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh version of the object or raise a ``TypeError``. 146ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 147ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh If encoding is not None, then all input strings will be 148ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh transformed into unicode using that encoding prior to JSON-encoding. 149ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh The default is UTF-8. 150ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 151ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh """ 152ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 153ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.skipkeys = skipkeys 154ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.ensure_ascii = ensure_ascii 155ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.check_circular = check_circular 156ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.allow_nan = allow_nan 157ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.sort_keys = sort_keys 158ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.indent = indent 159ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if separators is not None: 160ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.item_separator, self.key_separator = separators 161ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if default is not None: 162ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.default = default 163ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.encoding = encoding 164ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 165ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def default(self, o): 166ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh """Implement this method in a subclass such that it returns 167ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh a serializable object for ``o``, or calls the base implementation 168ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh (to raise a ``TypeError``). 169ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 170ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh For example, to support arbitrary iterators, you could 171ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh implement default like this:: 172ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 173ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def default(self, o): 174ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh try: 175ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh iterable = iter(o) 176ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh except TypeError: 177ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh pass 178ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh else: 179ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return list(iterable) 180ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # Let the base class default method raise the TypeError 181ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return JSONEncoder.default(self, o) 182ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 183ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh """ 184ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh raise TypeError(repr(o) + " is not JSON serializable") 185ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 186ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def encode(self, o): 187ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh """Return a JSON string representation of a Python data structure. 188ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 189ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh >>> JSONEncoder().encode({"foo": ["bar", "baz"]}) 190ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh '{"foo": ["bar", "baz"]}' 191ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 192ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh """ 193ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # This is for extremely simple cases and benchmarks. 194ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if isinstance(o, basestring): 195ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if isinstance(o, str): 196ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh _encoding = self.encoding 197ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if (_encoding is not None 198ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh and not (_encoding == 'utf-8')): 199ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh o = o.decode(_encoding) 200ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if self.ensure_ascii: 201ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return encode_basestring_ascii(o) 202ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh else: 203ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return encode_basestring(o) 204ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # This doesn't pass the iterator directly to ''.join() because the 205ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # exceptions aren't as detailed. The list call should be roughly 206ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # equivalent to the PySequence_Fast that ''.join() would do. 207ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh chunks = self.iterencode(o, _one_shot=True) 208ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if not isinstance(chunks, (list, tuple)): 209ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh chunks = list(chunks) 210ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return ''.join(chunks) 211ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 212ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def iterencode(self, o, _one_shot=False): 213ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh """Encode the given object and yield each string 214ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh representation as available. 215ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 216ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh For example:: 217ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 218ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh for chunk in JSONEncoder().iterencode(bigobject): 219ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh mysocket.write(chunk) 220ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 221ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh """ 222ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if self.check_circular: 223ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh markers = {} 224ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh else: 225ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh markers = None 226ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if self.ensure_ascii: 227ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh _encoder = encode_basestring_ascii 228ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh else: 229ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh _encoder = encode_basestring 230ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if self.encoding != 'utf-8': 231ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def _encoder(o, _orig_encoder=_encoder, _encoding=self.encoding): 232ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if isinstance(o, str): 233ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh o = o.decode(_encoding) 234ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return _orig_encoder(o) 235ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 236ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def floatstr(o, allow_nan=self.allow_nan, 237ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh _repr=FLOAT_REPR, _inf=INFINITY, _neginf=-INFINITY): 238ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # Check for specials. Note that this type of test is processor 239ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # and/or platform-specific, so do tests which don't depend on the 240ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # internals. 241ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 242ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if o != o: 243ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh text = 'NaN' 244ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh elif o == _inf: 245ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh text = 'Infinity' 246ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh elif o == _neginf: 247ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh text = '-Infinity' 248ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh else: 249ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return _repr(o) 250ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 251ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if not allow_nan: 252ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh raise ValueError( 253ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh "Out of range float values are not JSON compliant: " + 254ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh repr(o)) 255ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 256ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return text 257ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 258ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 259ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if (_one_shot and c_make_encoder is not None 260ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh and self.indent is None and not self.sort_keys): 261ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh _iterencode = c_make_encoder( 262ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh markers, self.default, _encoder, self.indent, 263ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.key_separator, self.item_separator, self.sort_keys, 264ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.skipkeys, self.allow_nan) 265ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh else: 266ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh _iterencode = _make_iterencode( 267ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh markers, self.default, _encoder, self.indent, floatstr, 268ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.key_separator, self.item_separator, self.sort_keys, 269ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.skipkeys, _one_shot) 270ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return _iterencode(o, 0) 271ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 272ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef _make_iterencode(markers, _default, _encoder, _indent, _floatstr, 273ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh _key_separator, _item_separator, _sort_keys, _skipkeys, _one_shot, 274ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh ## HACK: hand-optimized bytecode; turn globals into locals 275ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh ValueError=ValueError, 276ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh basestring=basestring, 277ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh dict=dict, 278ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh float=float, 279ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh id=id, 280ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh int=int, 281ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh isinstance=isinstance, 282ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh list=list, 283ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh long=long, 284ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh str=str, 285ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh tuple=tuple, 286ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh ): 287ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 288ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def _iterencode_list(lst, _current_indent_level): 289ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if not lst: 290ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh yield '[]' 291ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return 292ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if markers is not None: 293ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh markerid = id(lst) 294ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if markerid in markers: 295ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh raise ValueError("Circular reference detected") 296ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh markers[markerid] = lst 297ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh buf = '[' 298ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if _indent is not None: 299ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh _current_indent_level += 1 300ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh newline_indent = '\n' + (' ' * (_indent * _current_indent_level)) 301ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh separator = _item_separator + newline_indent 302ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh buf += newline_indent 303ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh else: 304ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh newline_indent = None 305ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh separator = _item_separator 306ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh first = True 307ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh for value in lst: 308ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if first: 309ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh first = False 310ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh else: 311ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh buf = separator 312ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if isinstance(value, basestring): 313ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh yield buf + _encoder(value) 314ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh elif value is None: 315ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh yield buf + 'null' 316ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh elif value is True: 317ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh yield buf + 'true' 318ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh elif value is False: 319ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh yield buf + 'false' 320ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh elif isinstance(value, (int, long)): 321ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh yield buf + str(value) 322ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh elif isinstance(value, float): 323ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh yield buf + _floatstr(value) 324ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh else: 325ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh yield buf 326ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if isinstance(value, (list, tuple)): 327ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh chunks = _iterencode_list(value, _current_indent_level) 328ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh elif isinstance(value, dict): 329ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh chunks = _iterencode_dict(value, _current_indent_level) 330ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh else: 331ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh chunks = _iterencode(value, _current_indent_level) 332ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh for chunk in chunks: 333ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh yield chunk 334ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if newline_indent is not None: 335ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh _current_indent_level -= 1 336ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh yield '\n' + (' ' * (_indent * _current_indent_level)) 337ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh yield ']' 338ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if markers is not None: 339ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh del markers[markerid] 340ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 341ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def _iterencode_dict(dct, _current_indent_level): 342ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if not dct: 343ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh yield '{}' 344ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return 345ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if markers is not None: 346ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh markerid = id(dct) 347ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if markerid in markers: 348ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh raise ValueError("Circular reference detected") 349ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh markers[markerid] = dct 350ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh yield '{' 351ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if _indent is not None: 352ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh _current_indent_level += 1 353ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh newline_indent = '\n' + (' ' * (_indent * _current_indent_level)) 354ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh item_separator = _item_separator + newline_indent 355ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh yield newline_indent 356ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh else: 357ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh newline_indent = None 358ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh item_separator = _item_separator 359ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh first = True 360ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if _sort_keys: 361ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh items = sorted(dct.items(), key=lambda kv: kv[0]) 362ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh else: 363ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh items = dct.iteritems() 364ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh for key, value in items: 365ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if isinstance(key, basestring): 366ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh pass 367ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # JavaScript is weakly typed for these, so it makes sense to 368ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # also allow them. Many encoders seem to do something like this. 369ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh elif isinstance(key, float): 370ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh key = _floatstr(key) 371ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh elif key is True: 372ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh key = 'true' 373ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh elif key is False: 374ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh key = 'false' 375ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh elif key is None: 376ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh key = 'null' 377ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh elif isinstance(key, (int, long)): 378ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh key = str(key) 379ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh elif _skipkeys: 380ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh continue 381ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh else: 382ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh raise TypeError("key " + repr(key) + " is not a string") 383ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if first: 384ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh first = False 385ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh else: 386ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh yield item_separator 387ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh yield _encoder(key) 388ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh yield _key_separator 389ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if isinstance(value, basestring): 390ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh yield _encoder(value) 391ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh elif value is None: 392ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh yield 'null' 393ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh elif value is True: 394ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh yield 'true' 395ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh elif value is False: 396ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh yield 'false' 397ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh elif isinstance(value, (int, long)): 398ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh yield str(value) 399ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh elif isinstance(value, float): 400ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh yield _floatstr(value) 401ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh else: 402ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if isinstance(value, (list, tuple)): 403ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh chunks = _iterencode_list(value, _current_indent_level) 404ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh elif isinstance(value, dict): 405ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh chunks = _iterencode_dict(value, _current_indent_level) 406ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh else: 407ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh chunks = _iterencode(value, _current_indent_level) 408ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh for chunk in chunks: 409ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh yield chunk 410ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if newline_indent is not None: 411ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh _current_indent_level -= 1 412ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh yield '\n' + (' ' * (_indent * _current_indent_level)) 413ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh yield '}' 414ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if markers is not None: 415ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh del markers[markerid] 416ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 417ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def _iterencode(o, _current_indent_level): 418ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if isinstance(o, basestring): 419ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh yield _encoder(o) 420ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh elif o is None: 421ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh yield 'null' 422ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh elif o is True: 423ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh yield 'true' 424ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh elif o is False: 425ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh yield 'false' 426ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh elif isinstance(o, (int, long)): 427ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh yield str(o) 428ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh elif isinstance(o, float): 429ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh yield _floatstr(o) 430ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh elif isinstance(o, (list, tuple)): 431ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh for chunk in _iterencode_list(o, _current_indent_level): 432ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh yield chunk 433ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh elif isinstance(o, dict): 434ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh for chunk in _iterencode_dict(o, _current_indent_level): 435ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh yield chunk 436ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh else: 437ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if markers is not None: 438ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh markerid = id(o) 439ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if markerid in markers: 440ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh raise ValueError("Circular reference detected") 441ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh markers[markerid] = o 442ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh o = _default(o) 443ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh for chunk in _iterencode(o, _current_indent_level): 444ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh yield chunk 445ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if markers is not None: 446ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh del markers[markerid] 447ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 448ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return _iterencode 449