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