@@ -293,37 +293,40 @@ def _iterencode_list(lst, _current_indent_level):
293
293
else :
294
294
newline_indent = None
295
295
separator = _item_separator
296
- first = True
297
- for value in lst :
298
- if first :
299
- first = False
300
- else :
296
+ for i , value in enumerate (lst ):
297
+ if i :
301
298
buf = separator
302
- if isinstance (value , str ):
303
- yield buf + _encoder (value )
304
- elif value is None :
305
- yield buf + 'null'
306
- elif value is True :
307
- yield buf + 'true'
308
- elif value is False :
309
- yield buf + 'false'
310
- elif isinstance (value , int ):
311
- # Subclasses of int/float may override __repr__, but we still
312
- # want to encode them as integers/floats in JSON. One example
313
- # within the standard library is IntEnum.
314
- yield buf + _intstr (value )
315
- elif isinstance (value , float ):
316
- # see comment above for int
317
- yield buf + _floatstr (value )
318
- else :
319
- yield buf
320
- if isinstance (value , (list , tuple )):
321
- chunks = _iterencode_list (value , _current_indent_level )
322
- elif isinstance (value , dict ):
323
- chunks = _iterencode_dict (value , _current_indent_level )
299
+ try :
300
+ if isinstance (value , str ):
301
+ yield buf + _encoder (value )
302
+ elif value is None :
303
+ yield buf + 'null'
304
+ elif value is True :
305
+ yield buf + 'true'
306
+ elif value is False :
307
+ yield buf + 'false'
308
+ elif isinstance (value , int ):
309
+ # Subclasses of int/float may override __repr__, but we still
310
+ # want to encode them as integers/floats in JSON. One example
311
+ # within the standard library is IntEnum.
312
+ yield buf + _intstr (value )
313
+ elif isinstance (value , float ):
314
+ # see comment above for int
315
+ yield buf + _floatstr (value )
324
316
else :
325
- chunks = _iterencode (value , _current_indent_level )
326
- yield from chunks
317
+ yield buf
318
+ if isinstance (value , (list , tuple )):
319
+ chunks = _iterencode_list (value , _current_indent_level )
320
+ elif isinstance (value , dict ):
321
+ chunks = _iterencode_dict (value , _current_indent_level )
322
+ else :
323
+ chunks = _iterencode (value , _current_indent_level )
324
+ yield from chunks
325
+ except GeneratorExit :
326
+ raise
327
+ except BaseException as exc :
328
+ exc .add_note (f'when serializing { type (lst ).__name__ } item { i } ' )
329
+ raise
327
330
if newline_indent is not None :
328
331
_current_indent_level -= 1
329
332
yield '\n ' + _indent * _current_indent_level
@@ -382,28 +385,34 @@ def _iterencode_dict(dct, _current_indent_level):
382
385
yield item_separator
383
386
yield _encoder (key )
384
387
yield _key_separator
385
- if isinstance (value , str ):
386
- yield _encoder (value )
387
- elif value is None :
388
- yield 'null'
389
- elif value is True :
390
- yield 'true'
391
- elif value is False :
392
- yield 'false'
393
- elif isinstance (value , int ):
394
- # see comment for int/float in _make_iterencode
395
- yield _intstr (value )
396
- elif isinstance (value , float ):
397
- # see comment for int/float in _make_iterencode
398
- yield _floatstr (value )
399
- else :
400
- if isinstance (value , (list , tuple )):
401
- chunks = _iterencode_list (value , _current_indent_level )
402
- elif isinstance (value , dict ):
403
- chunks = _iterencode_dict (value , _current_indent_level )
388
+ try :
389
+ if isinstance (value , str ):
390
+ yield _encoder (value )
391
+ elif value is None :
392
+ yield 'null'
393
+ elif value is True :
394
+ yield 'true'
395
+ elif value is False :
396
+ yield 'false'
397
+ elif isinstance (value , int ):
398
+ # see comment for int/float in _make_iterencode
399
+ yield _intstr (value )
400
+ elif isinstance (value , float ):
401
+ # see comment for int/float in _make_iterencode
402
+ yield _floatstr (value )
404
403
else :
405
- chunks = _iterencode (value , _current_indent_level )
406
- yield from chunks
404
+ if isinstance (value , (list , tuple )):
405
+ chunks = _iterencode_list (value , _current_indent_level )
406
+ elif isinstance (value , dict ):
407
+ chunks = _iterencode_dict (value , _current_indent_level )
408
+ else :
409
+ chunks = _iterencode (value , _current_indent_level )
410
+ yield from chunks
411
+ except GeneratorExit :
412
+ raise
413
+ except BaseException as exc :
414
+ exc .add_note (f'when serializing { type (dct ).__name__ } item { key !r} ' )
415
+ raise
407
416
if newline_indent is not None :
408
417
_current_indent_level -= 1
409
418
yield '\n ' + _indent * _current_indent_level
@@ -436,8 +445,14 @@ def _iterencode(o, _current_indent_level):
436
445
if markerid in markers :
437
446
raise ValueError ("Circular reference detected" )
438
447
markers [markerid ] = o
439
- o = _default (o )
440
- yield from _iterencode (o , _current_indent_level )
448
+ newobj = _default (o )
449
+ try :
450
+ yield from _iterencode (newobj , _current_indent_level )
451
+ except GeneratorExit :
452
+ raise
453
+ except BaseException as exc :
454
+ exc .add_note (f'when serializing { type (o ).__name__ } object' )
455
+ raise
441
456
if markers is not None :
442
457
del markers [markerid ]
443
458
return _iterencode
0 commit comments