Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/simplejson-4.1.1-py3.11-linux-x86_64.egg/simplejson/encoder.py: 19%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

445 statements  

1"""Implementation of JSONEncoder 

2""" 

3from __future__ import absolute_import 

4import re 

5from operator import itemgetter 

6# Do not import Decimal directly to avoid reload issues 

7import decimal 

8import sys 

9from .compat import binary_type, text_type, string_types, integer_types, PY3 

10 

11# PEP 678 add_note() is available on Python 3.11+ 

12_HAS_ADD_NOTE = sys.version_info >= (3, 11) 

13 

14def _import_speedups(): 

15 try: 

16 from . import _speedups 

17 return (_speedups.encode_basestring_ascii, 

18 _speedups.encode_basestring, 

19 _speedups.make_encoder) 

20 except ImportError: 

21 return None, None, None 

22c_encode_basestring_ascii, c_encode_basestring, c_make_encoder = ( 

23 _import_speedups()) 

24 

25from .decoder import PosInf 

26from .raw_json import RawJSON 

27 

28ESCAPE = re.compile(r'[\x00-\x1f\\"]') 

29ESCAPE_ASCII = re.compile(r'([\\"]|[^\ -~])') 

30HAS_UTF8 = re.compile(r'[\x80-\xff]') 

31ESCAPE_DCT = { 

32 '\\': '\\\\', 

33 '"': '\\"', 

34 '\b': '\\b', 

35 '\f': '\\f', 

36 '\n': '\\n', 

37 '\r': '\\r', 

38 '\t': '\\t', 

39} 

40for i in range(0x20): 

41 ESCAPE_DCT.setdefault(chr(i), '\\u%04x' % (i,)) 

42del i 

43 

44FLOAT_REPR = repr 

45 

46_NAN = float('nan') 

47_INFINITY = float('inf') 

48 

49 

50def _encode_decimal(d, _floatstr): 

51 """Return the JSON representation of a ``Decimal``. 

52 

53 Finite Decimals are stringified as-is, preserving precision and trailing 

54 zeros. Non-finite Decimals (``NaN``, ``sNaN``, ``Infinity``) are routed 

55 through the same ``allow_nan``/``ignore_nan`` handling as floats so they 

56 never emit invalid JSON (see #149). 

57 

58 ``str(Decimal)`` yields a leading ``-`` sign at most (never ``+``); a 

59 finite value's first significant character is always a digit, while a 

60 non-finite value's is a letter (``N``, ``s`` or ``I``). So a single 

61 ``str()`` plus a one/two character check distinguishes the two. 

62 """ 

63 s = str(d) 

64 c0 = s[:1] 

65 c = s[1:2] if c0 == '-' else c0 

66 if '0' <= c <= '9': 

67 # First significant character is a digit: finite Decimal. 

68 return s 

69 # Non-finite Decimal. ``N``/``s`` -> NaN (float(Decimal('sNaN')) raises, 

70 # so map both quiet and signaling NaN to a plain NaN); ``I`` -> Infinity. 

71 if c == 'I': 

72 return _floatstr(-_INFINITY if c0 == '-' else _INFINITY) 

73 return _floatstr(_NAN) 

74 

75# dict-like types that should be encoded as JSON objects. 

76# frozendict is a builtin added in CPython 3.15 (PEP 814). 

77if sys.version_info >= (3, 15): 

78 _dict_types = (dict, frozendict) 

79else: 

80 _dict_types = dict 

81 

82def py_encode_basestring(s, _PY3=PY3, _q=u'"'): 

83 """Return a JSON representation of a Python string 

84 

85 """ 

86 if _PY3: 

87 if isinstance(s, bytes): 

88 s = str(s, 'utf-8') 

89 elif type(s) is not str: 

90 # convert an str subclass instance to exact str 

91 # raise a TypeError otherwise 

92 s = str.__str__(s) 

93 else: 

94 if isinstance(s, str) and HAS_UTF8.search(s) is not None: 

95 s = unicode(s, 'utf-8') 

96 elif type(s) not in (str, unicode): 

97 # convert an str subclass instance to exact str 

98 # convert a unicode subclass instance to exact unicode 

99 # raise a TypeError otherwise 

100 if isinstance(s, str): 

101 s = str.__str__(s) 

102 else: 

103 s = unicode.__getnewargs__(s)[0] 

104 def replace(match): 

105 return ESCAPE_DCT[match.group(0)] 

106 return _q + ESCAPE.sub(replace, s) + _q 

107 

108 

109def py_encode_basestring_ascii(s, _PY3=PY3): 

110 """Return an ASCII-only JSON representation of a Python string 

111 

112 """ 

113 if _PY3: 

114 if isinstance(s, bytes): 

115 s = str(s, 'utf-8') 

116 elif type(s) is not str: 

117 # convert an str subclass instance to exact str 

118 # raise a TypeError otherwise 

119 s = str.__str__(s) 

120 else: 

121 if isinstance(s, str) and HAS_UTF8.search(s) is not None: 

122 s = unicode(s, 'utf-8') 

123 elif type(s) not in (str, unicode): 

124 # convert an str subclass instance to exact str 

125 # convert a unicode subclass instance to exact unicode 

126 # raise a TypeError otherwise 

127 if isinstance(s, str): 

128 s = str.__str__(s) 

129 else: 

130 s = unicode.__getnewargs__(s)[0] 

131 def replace(match): 

132 s = match.group(0) 

133 try: 

134 return ESCAPE_DCT[s] 

135 except KeyError: 

136 n = ord(s) 

137 if n < 0x10000: 

138 return '\\u%04x' % (n,) 

139 else: 

140 # surrogate pair 

141 n -= 0x10000 

142 s1 = 0xd800 | ((n >> 10) & 0x3ff) 

143 s2 = 0xdc00 | (n & 0x3ff) 

144 return '\\u%04x\\u%04x' % (s1, s2) 

145 return '"' + str(ESCAPE_ASCII.sub(replace, s)) + '"' 

146 

147 

148encode_basestring_ascii = ( 

149 c_encode_basestring_ascii or py_encode_basestring_ascii) 

150 

151encode_basestring = ( 

152 c_encode_basestring or py_encode_basestring) 

153 

154class JSONEncoder(object): 

155 """Extensible JSON <http://json.org> encoder for Python data structures. 

156 

157 Supports the following objects and types by default: 

158 

159 +-------------------+---------------+ 

160 | Python | JSON | 

161 +===================+===============+ 

162 | dict, namedtuple | object | 

163 +-------------------+---------------+ 

164 | list, tuple | array | 

165 +-------------------+---------------+ 

166 | str, unicode | string | 

167 +-------------------+---------------+ 

168 | int, long, float | number | 

169 +-------------------+---------------+ 

170 | True | true | 

171 +-------------------+---------------+ 

172 | False | false | 

173 +-------------------+---------------+ 

174 | None | null | 

175 +-------------------+---------------+ 

176 

177 To extend this to recognize other objects, subclass and implement a 

178 ``.default()`` method with another method that returns a serializable 

179 object for ``o`` if possible, otherwise it should call the superclass 

180 implementation (to raise ``TypeError``). 

181 

182 """ 

183 item_separator = ', ' 

184 key_separator = ': ' 

185 

186 def __init__(self, skipkeys=False, ensure_ascii=True, 

187 check_circular=True, allow_nan=False, sort_keys=False, 

188 indent=None, separators=None, encoding='utf-8', default=None, 

189 use_decimal=True, namedtuple_as_object=True, 

190 tuple_as_array=True, bigint_as_string=False, 

191 item_sort_key=None, for_json=False, ignore_nan=False, 

192 int_as_string_bitcount=None, iterable_as_array=False): 

193 """Constructor for JSONEncoder, with sensible defaults. 

194 

195 If skipkeys is false, then it is a TypeError to attempt 

196 encoding of keys that are not str, int, long, float or None. If 

197 skipkeys is True, such items are simply skipped. 

198 

199 If ensure_ascii is true, the output is guaranteed to be str 

200 objects with all incoming unicode characters escaped. If 

201 ensure_ascii is false, the output will be unicode object. 

202 

203 If check_circular is true, then lists, dicts, and custom encoded 

204 objects will be checked for circular references during encoding to 

205 prevent an infinite recursion (which would cause an OverflowError). 

206 Otherwise, no such check takes place. 

207 

208 If allow_nan is true (default: False), then out of range float 

209 values (nan, inf, -inf) will be serialized to 

210 their JavaScript equivalents (NaN, Infinity, -Infinity) 

211 instead of raising a ValueError. See 

212 ignore_nan for ECMA-262 compliant behavior. 

213 

214 If sort_keys is true, then the output of dictionaries will be 

215 sorted by key; this is useful for regression tests to ensure 

216 that JSON serializations can be compared on a day-to-day basis. 

217 

218 If indent is a string, then JSON array elements and object members 

219 will be pretty-printed with a newline followed by that string repeated 

220 for each level of nesting. ``None`` (the default) selects the most compact 

221 representation without any newlines. For backwards compatibility with 

222 versions of simplejson earlier than 2.1.0, an integer is also accepted 

223 and is converted to a string with that many spaces. 

224 

225 If specified, separators should be an (item_separator, key_separator) 

226 tuple. The default is (', ', ': ') if *indent* is ``None`` and 

227 (',', ': ') otherwise. To get the most compact JSON representation, 

228 you should specify (',', ':') to eliminate whitespace. 

229 

230 If specified, default is a function that gets called for objects 

231 that can't otherwise be serialized. It should return a JSON encodable 

232 version of the object or raise a ``TypeError``. 

233 

234 If encoding is not None, then all input strings will be 

235 transformed into unicode using that encoding prior to JSON-encoding. 

236 The default is UTF-8. 

237 

238 If use_decimal is true (default: ``True``), ``decimal.Decimal`` will 

239 be supported directly by the encoder. For the inverse, decode JSON 

240 with ``parse_float=decimal.Decimal``. 

241 

242 If namedtuple_as_object is true (the default), objects with 

243 ``_asdict()`` methods will be encoded as JSON objects. 

244 

245 If tuple_as_array is true (the default), tuple (and subclasses) will 

246 be encoded as JSON arrays. 

247 

248 If *iterable_as_array* is true (default: ``False``), 

249 any object not in the above table that implements ``__iter__()`` 

250 will be encoded as a JSON array. 

251 

252 If bigint_as_string is true (not the default), ints 2**53 and higher 

253 or lower than -2**53 will be encoded as strings. This is to avoid the 

254 rounding that happens in Javascript otherwise. 

255 

256 If int_as_string_bitcount is a positive number (n), then int of size 

257 greater than or equal to 2**n or lower than or equal to -2**n will be 

258 encoded as strings. 

259 

260 If specified, item_sort_key is a callable used to sort the items in 

261 each dictionary. This is useful if you want to sort items other than 

262 in alphabetical order by key. 

263 

264 If for_json is true (not the default), objects with a ``for_json()`` 

265 method will use the return value of that method for encoding as JSON 

266 instead of the object. 

267 

268 If *ignore_nan* is true (default: ``False``), then out of range 

269 :class:`float` values (``nan``, ``inf``, ``-inf``) will be serialized 

270 as ``null`` in compliance with the ECMA-262 specification. If true, 

271 this will override *allow_nan*. 

272 

273 """ 

274 

275 self.skipkeys = skipkeys 

276 self.ensure_ascii = ensure_ascii 

277 self.check_circular = check_circular 

278 self.allow_nan = allow_nan 

279 self.sort_keys = sort_keys 

280 self.use_decimal = use_decimal 

281 self.namedtuple_as_object = namedtuple_as_object 

282 self.tuple_as_array = tuple_as_array 

283 self.iterable_as_array = iterable_as_array 

284 self.bigint_as_string = bigint_as_string 

285 self.item_sort_key = item_sort_key 

286 self.for_json = for_json 

287 self.ignore_nan = ignore_nan 

288 self.int_as_string_bitcount = int_as_string_bitcount 

289 if indent is not None and not isinstance(indent, string_types): 

290 indent = indent * ' ' 

291 self.indent = indent 

292 if separators is not None: 

293 self.item_separator, self.key_separator = separators 

294 elif indent is not None: 

295 self.item_separator = ',' 

296 if default is not None: 

297 self.default = default 

298 self.encoding = encoding 

299 

300 def default(self, o): 

301 """Implement this method in a subclass such that it returns 

302 a serializable object for ``o``, or calls the base implementation 

303 (to raise a ``TypeError``). 

304 

305 For example, to support arbitrary iterators, you could 

306 implement default like this:: 

307 

308 def default(self, o): 

309 try: 

310 iterable = iter(o) 

311 except TypeError: 

312 pass 

313 else: 

314 return list(iterable) 

315 return JSONEncoder.default(self, o) 

316 

317 """ 

318 raise TypeError('Object of type %s is not JSON serializable' % 

319 o.__class__.__name__) 

320 

321 def encode(self, o): 

322 """Return a JSON string representation of a Python data structure. 

323 

324 >>> from simplejson import JSONEncoder 

325 >>> JSONEncoder().encode({"foo": ["bar", "baz"]}) 

326 '{"foo": ["bar", "baz"]}' 

327 

328 """ 

329 # This is for extremely simple cases and benchmarks. 

330 if isinstance(o, binary_type): 

331 _encoding = self.encoding 

332 if (_encoding is not None and not (_encoding == 'utf-8')): 

333 o = text_type(o, _encoding) 

334 if isinstance(o, string_types): 

335 if self.ensure_ascii: 

336 return encode_basestring_ascii(o) 

337 else: 

338 return encode_basestring(o) 

339 # This doesn't pass the iterator directly to ''.join() because the 

340 # exceptions aren't as detailed. The list call should be roughly 

341 # equivalent to the PySequence_Fast that ''.join() would do. 

342 chunks = self.iterencode(o) 

343 if not isinstance(chunks, (list, tuple)): 

344 chunks = list(chunks) 

345 if self.ensure_ascii: 

346 return ''.join(chunks) 

347 else: 

348 return u''.join(chunks) 

349 

350 def iterencode(self, o): 

351 """Encode the given object and yield each string 

352 representation as available. 

353 

354 For example:: 

355 

356 for chunk in JSONEncoder().iterencode(bigobject): 

357 mysocket.write(chunk) 

358 

359 """ 

360 if self.check_circular: 

361 markers = {} 

362 else: 

363 markers = None 

364 if self.ensure_ascii: 

365 _encoder = encode_basestring_ascii 

366 else: 

367 _encoder = encode_basestring 

368 if self.encoding != 'utf-8' and self.encoding is not None: 

369 def _encoder(o, _orig_encoder=_encoder, _encoding=self.encoding): 

370 if isinstance(o, binary_type): 

371 o = text_type(o, _encoding) 

372 return _orig_encoder(o) 

373 

374 def floatstr(o, allow_nan=self.allow_nan, ignore_nan=self.ignore_nan, 

375 _repr=FLOAT_REPR, _inf=PosInf, _neginf=-PosInf): 

376 # Check for specials. Note that this type of test is processor 

377 # and/or platform-specific, so do tests which don't depend on 

378 # the internals. 

379 

380 if o != o: 

381 text = 'NaN' 

382 elif o == _inf: 

383 text = 'Infinity' 

384 elif o == _neginf: 

385 text = '-Infinity' 

386 else: 

387 if type(o) != float: 

388 # See #118, do not trust custom str/repr 

389 o = float(o) 

390 return _repr(o) 

391 

392 if ignore_nan: 

393 text = 'null' 

394 elif not allow_nan: 

395 raise ValueError( 

396 "Out of range float values are not JSON compliant: " + 

397 repr(o)) 

398 

399 return text 

400 

401 key_memo = {} 

402 int_as_string_bitcount = ( 

403 53 if self.bigint_as_string else self.int_as_string_bitcount) 

404 if c_make_encoder is not None: 

405 _iterencode = c_make_encoder( 

406 markers, self.default, _encoder, self.indent, 

407 self.key_separator, self.item_separator, self.sort_keys, 

408 self.skipkeys, self.allow_nan, key_memo, self.use_decimal, 

409 self.namedtuple_as_object, self.tuple_as_array, 

410 int_as_string_bitcount, 

411 self.item_sort_key, self.encoding, self.for_json, 

412 self.ignore_nan, decimal.Decimal, self.iterable_as_array) 

413 else: 

414 _iterencode = _make_iterencode( 

415 markers, self.default, _encoder, self.indent, floatstr, 

416 self.key_separator, self.item_separator, self.sort_keys, 

417 self.skipkeys, self.use_decimal, 

418 self.namedtuple_as_object, self.tuple_as_array, 

419 int_as_string_bitcount, 

420 self.item_sort_key, self.encoding, self.for_json, 

421 self.iterable_as_array, Decimal=decimal.Decimal) 

422 try: 

423 return _iterencode(o, 0) 

424 finally: 

425 key_memo.clear() 

426 

427 

428class JSONEncoderForHTML(JSONEncoder): 

429 """An encoder that produces JSON safe to embed in HTML. 

430 

431 To embed JSON content in, say, a script tag on a web page, the 

432 characters &, < and > should be escaped. They cannot be escaped 

433 with the usual entities (e.g. &amp;) because they are not expanded 

434 within <script> tags. 

435 

436 This class also escapes the line separator and paragraph separator 

437 characters U+2028 and U+2029, irrespective of the ensure_ascii setting, 

438 as these characters are not valid in JavaScript strings (see 

439 http://timelessrepo.com/json-isnt-a-javascript-subset). 

440 """ 

441 

442 def encode(self, o): 

443 # Override JSONEncoder.encode because it has hacks for 

444 # performance that make things more complicated. 

445 chunks = self.iterencode(o) 

446 if self.ensure_ascii: 

447 return ''.join(chunks) 

448 else: 

449 return u''.join(chunks) 

450 

451 def iterencode(self, o): 

452 chunks = super(JSONEncoderForHTML, self).iterencode(o) 

453 for chunk in chunks: 

454 chunk = chunk.replace('&', '\\u0026') 

455 chunk = chunk.replace('<', '\\u003c') 

456 chunk = chunk.replace('>', '\\u003e') 

457 

458 if not self.ensure_ascii: 

459 chunk = chunk.replace(u'\u2028', '\\u2028') 

460 chunk = chunk.replace(u'\u2029', '\\u2029') 

461 

462 yield chunk 

463 

464 

465def _make_iterencode(markers, _default, _encoder, _indent, _floatstr, 

466 _key_separator, _item_separator, _sort_keys, _skipkeys, 

467 _use_decimal, _namedtuple_as_object, _tuple_as_array, 

468 _int_as_string_bitcount, _item_sort_key, 

469 _encoding,_for_json, 

470 _iterable_as_array, 

471 ## HACK: hand-optimized bytecode; turn globals into locals 

472 _PY3=PY3, 

473 ValueError=ValueError, 

474 string_types=string_types, 

475 Decimal=None, 

476 dict=dict, 

477 _dict_types=_dict_types, 

478 float=float, 

479 id=id, 

480 integer_types=integer_types, 

481 isinstance=isinstance, 

482 list=list, 

483 str=str, 

484 tuple=tuple, 

485 iter=iter, 

486 ): 

487 if _use_decimal and Decimal is None: 

488 Decimal = decimal.Decimal 

489 if _item_sort_key and not callable(_item_sort_key): 

490 raise TypeError("item_sort_key must be None or callable") 

491 elif _sort_keys and not _item_sort_key: 

492 _item_sort_key = itemgetter(0) 

493 

494 if (_int_as_string_bitcount is not None and 

495 (_int_as_string_bitcount <= 0 or 

496 not isinstance(_int_as_string_bitcount, integer_types))): 

497 raise TypeError("int_as_string_bitcount must be a positive integer") 

498 

499 def call_method(obj, method_name): 

500 method = getattr(obj, method_name, None) 

501 if callable(method): 

502 try: 

503 return (method(),) 

504 except TypeError: 

505 pass 

506 return None 

507 

508 def _encode_int(value): 

509 skip_quoting = ( 

510 _int_as_string_bitcount is None 

511 or 

512 _int_as_string_bitcount < 1 

513 ) 

514 if type(value) not in integer_types: 

515 # See #118, do not trust custom str/repr 

516 value = int(value) 

517 if ( 

518 skip_quoting or 

519 (-1 << _int_as_string_bitcount) 

520 < value < 

521 (1 << _int_as_string_bitcount) 

522 ): 

523 return str(value) 

524 return '"' + str(value) + '"' 

525 

526 def _iterencode_list(lst, _current_indent_level): 

527 if not lst: 

528 yield '[]' 

529 return 

530 if markers is not None: 

531 markerid = id(lst) 

532 if markerid in markers: 

533 raise ValueError("Circular reference detected") 

534 markers[markerid] = lst 

535 buf = '[' 

536 if _indent is not None: 

537 _current_indent_level += 1 

538 newline_indent = '\n' + (_indent * _current_indent_level) 

539 separator = _item_separator + newline_indent 

540 buf += newline_indent 

541 else: 

542 newline_indent = None 

543 separator = _item_separator 

544 first = True 

545 for i, value in enumerate(lst): 

546 if first: 

547 first = False 

548 else: 

549 buf = separator 

550 try: 

551 if isinstance(value, string_types): 

552 yield buf + _encoder(value) 

553 elif _PY3 and isinstance(value, bytes) and _encoding is not None: 

554 yield buf + _encoder(value) 

555 elif isinstance(value, RawJSON): 

556 yield buf + value.encoded_json 

557 elif value is None: 

558 yield buf + 'null' 

559 elif value is True: 

560 yield buf + 'true' 

561 elif value is False: 

562 yield buf + 'false' 

563 elif isinstance(value, integer_types): 

564 yield buf + _encode_int(value) 

565 elif isinstance(value, float): 

566 yield buf + _floatstr(value) 

567 elif _use_decimal and isinstance(value, Decimal): 

568 yield buf + _encode_decimal(value, _floatstr) 

569 else: 

570 yield buf 

571 for_json = _for_json and call_method(value, 'for_json') 

572 if for_json: 

573 chunks = _iterencode(for_json[0], _current_indent_level) 

574 else: 

575 _asdict = _namedtuple_as_object and call_method(value, '_asdict') 

576 if _asdict: 

577 dct = _asdict[0] 

578 if not isinstance(dct, dict): 

579 raise TypeError("_asdict() must return a dict, not %s" % (type(dct).__name__,)) 

580 chunks = _iterencode_dict(dct, 

581 _current_indent_level) 

582 elif isinstance(value, list): 

583 chunks = _iterencode_list(value, _current_indent_level) 

584 elif _tuple_as_array and isinstance(value, tuple): 

585 chunks = _iterencode_list(value, _current_indent_level) 

586 elif isinstance(value, _dict_types): 

587 chunks = _iterencode_dict(value, _current_indent_level) 

588 else: 

589 chunks = _iterencode(value, _current_indent_level) 

590 for chunk in chunks: 

591 yield chunk 

592 except BaseException as exc: 

593 if _HAS_ADD_NOTE: 

594 exc.add_note( 

595 'when serializing %s item %d' 

596 % (type(lst).__name__, i)) 

597 raise 

598 if first: 

599 # iterable_as_array misses the fast path at the top 

600 yield '[]' 

601 else: 

602 if newline_indent is not None: 

603 _current_indent_level -= 1 

604 yield '\n' + (_indent * _current_indent_level) 

605 yield ']' 

606 if markers is not None: 

607 del markers[markerid] 

608 

609 def _stringify_key(key): 

610 if isinstance(key, string_types): # pragma: no cover 

611 pass 

612 elif _PY3 and isinstance(key, bytes) and _encoding is not None: 

613 key = str(key, _encoding) 

614 elif isinstance(key, float): 

615 key = _floatstr(key) 

616 elif key is True: 

617 key = 'true' 

618 elif key is False: 

619 key = 'false' 

620 elif key is None: 

621 key = 'null' 

622 elif isinstance(key, integer_types): 

623 if type(key) not in integer_types: 

624 # See #118, do not trust custom str/repr 

625 key = int(key) 

626 key = str(key) 

627 elif _use_decimal and isinstance(key, Decimal): 

628 key = _encode_decimal(key, _floatstr) 

629 elif _skipkeys: 

630 key = None 

631 else: 

632 raise TypeError('keys must be str, int, float, bool or None, ' 

633 'not %s' % key.__class__.__name__) 

634 return key 

635 

636 def _iterencode_dict(dct, _current_indent_level): 

637 if not dct: 

638 yield '{}' 

639 return 

640 if markers is not None: 

641 markerid = id(dct) 

642 if markerid in markers: 

643 raise ValueError("Circular reference detected") 

644 markers[markerid] = dct 

645 yield '{' 

646 if _indent is not None: 

647 _current_indent_level += 1 

648 newline_indent = '\n' + (_indent * _current_indent_level) 

649 item_separator = _item_separator + newline_indent 

650 yield newline_indent 

651 else: 

652 newline_indent = None 

653 item_separator = _item_separator 

654 first = True 

655 if _PY3: 

656 iteritems = dct.items() 

657 else: 

658 iteritems = dct.iteritems() 

659 if _item_sort_key: 

660 items = [] 

661 for k, v in dct.items(): 

662 if not isinstance(k, string_types): 

663 k = _stringify_key(k) 

664 if k is None: 

665 continue 

666 items.append((k, v)) 

667 items.sort(key=_item_sort_key) 

668 else: 

669 items = iteritems 

670 for key, value in items: 

671 if not (_item_sort_key or isinstance(key, string_types)): 

672 key = _stringify_key(key) 

673 if key is None: 

674 # _skipkeys must be True 

675 continue 

676 if first: 

677 first = False 

678 else: 

679 yield item_separator 

680 yield _encoder(key) 

681 yield _key_separator 

682 try: 

683 if isinstance(value, string_types): 

684 yield _encoder(value) 

685 elif _PY3 and isinstance(value, bytes) and _encoding is not None: 

686 yield _encoder(value) 

687 elif isinstance(value, RawJSON): 

688 yield value.encoded_json 

689 elif value is None: 

690 yield 'null' 

691 elif value is True: 

692 yield 'true' 

693 elif value is False: 

694 yield 'false' 

695 elif isinstance(value, integer_types): 

696 yield _encode_int(value) 

697 elif isinstance(value, float): 

698 yield _floatstr(value) 

699 elif _use_decimal and isinstance(value, Decimal): 

700 yield _encode_decimal(value, _floatstr) 

701 else: 

702 for_json = _for_json and call_method(value, 'for_json') 

703 if for_json: 

704 chunks = _iterencode(for_json[0], _current_indent_level) 

705 else: 

706 _asdict = _namedtuple_as_object and call_method(value, '_asdict') 

707 if _asdict: 

708 dct = _asdict[0] 

709 if not isinstance(dct, dict): 

710 raise TypeError("_asdict() must return a dict, not %s" % (type(dct).__name__,)) 

711 chunks = _iterencode_dict(dct, 

712 _current_indent_level) 

713 elif isinstance(value, list): 

714 chunks = _iterencode_list(value, _current_indent_level) 

715 elif _tuple_as_array and isinstance(value, tuple): 

716 chunks = _iterencode_list(value, _current_indent_level) 

717 elif isinstance(value, _dict_types): 

718 chunks = _iterencode_dict(value, _current_indent_level) 

719 else: 

720 chunks = _iterencode(value, _current_indent_level) 

721 for chunk in chunks: 

722 yield chunk 

723 except BaseException as exc: 

724 if _HAS_ADD_NOTE: 

725 exc.add_note( 

726 'when serializing %s item %r' 

727 % (type(dct).__name__, key)) 

728 raise 

729 if newline_indent is not None: 

730 _current_indent_level -= 1 

731 yield '\n' + (_indent * _current_indent_level) 

732 yield '}' 

733 if markers is not None: 

734 del markers[markerid] 

735 

736 def _iterencode(o, _current_indent_level): 

737 if isinstance(o, string_types): 

738 yield _encoder(o) 

739 elif _PY3 and isinstance(o, bytes) and _encoding is not None: 

740 yield _encoder(o) 

741 elif isinstance(o, RawJSON): 

742 yield o.encoded_json 

743 elif o is None: 

744 yield 'null' 

745 elif o is True: 

746 yield 'true' 

747 elif o is False: 

748 yield 'false' 

749 elif isinstance(o, integer_types): 

750 yield _encode_int(o) 

751 elif isinstance(o, float): 

752 yield _floatstr(o) 

753 else: 

754 for_json = _for_json and call_method(o, 'for_json') 

755 if for_json: 

756 for chunk in _iterencode(for_json[0], _current_indent_level): 

757 yield chunk 

758 else: 

759 _asdict = _namedtuple_as_object and call_method(o, '_asdict') 

760 if _asdict: 

761 dct = _asdict[0] 

762 if not isinstance(dct, dict): 

763 raise TypeError("_asdict() must return a dict, not %s" % (type(dct).__name__,)) 

764 for chunk in _iterencode_dict(dct, _current_indent_level): 

765 yield chunk 

766 elif isinstance(o, list): 

767 for chunk in _iterencode_list(o, _current_indent_level): 

768 yield chunk 

769 elif (_tuple_as_array and isinstance(o, tuple)): 

770 for chunk in _iterencode_list(o, _current_indent_level): 

771 yield chunk 

772 elif isinstance(o, _dict_types): 

773 for chunk in _iterencode_dict(o, _current_indent_level): 

774 yield chunk 

775 elif _use_decimal and isinstance(o, Decimal): 

776 yield _encode_decimal(o, _floatstr) 

777 else: 

778 while _iterable_as_array: 

779 # Markers are not checked here because it is valid for 

780 # an iterable to return self. 

781 try: 

782 o = iter(o) 

783 except TypeError: 

784 break 

785 for chunk in _iterencode_list(o, _current_indent_level): 

786 yield chunk 

787 return 

788 if markers is not None: 

789 markerid = id(o) 

790 if markerid in markers: 

791 raise ValueError("Circular reference detected") 

792 markers[markerid] = o 

793 try: 

794 o = _default(o) 

795 for chunk in _iterencode(o, _current_indent_level): 

796 yield chunk 

797 except BaseException as exc: 

798 if _HAS_ADD_NOTE: 

799 exc.add_note( 

800 'when serializing %s object' 

801 % type(o).__name__) 

802 raise 

803 if markers is not None: 

804 del markers[markerid] 

805 

806 return _iterencode