@@ -293,37 +293,40 @@ def _iterencode_list(lst, _current_indent_level):
293293 else :
294294 newline_indent = None
295295 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 :
301298 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 )
324316 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
327330 if newline_indent is not None :
328331 _current_indent_level -= 1
329332 yield '\n ' + _indent * _current_indent_level
@@ -382,28 +385,34 @@ def _iterencode_dict(dct, _current_indent_level):
382385 yield item_separator
383386 yield _encoder (key )
384387 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 )
404403 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
407416 if newline_indent is not None :
408417 _current_indent_level -= 1
409418 yield '\n ' + _indent * _current_indent_level
@@ -436,8 +445,14 @@ def _iterencode(o, _current_indent_level):
436445 if markerid in markers :
437446 raise ValueError ("Circular reference detected" )
438447 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
441456 if markers is not None :
442457 del markers [markerid ]
443458 return _iterencode
0 commit comments