@@ -187,14 +187,19 @@ def isreadable(self, object):
187187 return readable and not recursive
188188
189189 def _format (self , object , stream , indent , allowance , context , level ):
190+ # Width of any "key: " prefix already written on the current line by
191+ # _format_child(). In expand mode `indent` is the block indent and so
192+ # does not include it, but it still consumes width here.
193+ prefix_len = self ._pending_prefix_len
194+ self ._pending_prefix_len = 0
190195 objid = id (object )
191196 if objid in context :
192197 stream .write (_recursion (object ))
193198 self ._recursive = True
194199 self ._readable = False
195200 return
196201 rep = self ._repr (object , context , level )
197- max_width = self ._width - indent - allowance
202+ max_width = self ._width - indent - prefix_len - allowance
198203 if len (rep ) > max_width :
199204 p = self ._dispatch .get (type (object ).__repr__ , None )
200205 # Lazy import to improve module import time
@@ -232,6 +237,22 @@ def _child_indent(self, indent, prefix_len):
232237 return indent
233238 return indent + prefix_len
234239
240+ # Set by _format_child() immediately before it calls _format(), and
241+ # consumed there. Passing it out of band keeps _format()'s signature
242+ # unchanged for third-party subclasses that override it.
243+ _pending_prefix_len = 0
244+
245+ def _format_child (self , object , stream , indent , allowance , context , level ,
246+ prefix_len ):
247+ if self ._expand :
248+ # Aligned mode folds the prefix into the indent (see
249+ # _child_indent), so only expand mode needs to report it.
250+ self ._pending_prefix_len = prefix_len
251+ try :
252+ self ._format (object , stream , indent , allowance , context , level )
253+ finally :
254+ self ._pending_prefix_len = 0
255+
235256 def _write_indent_padding (self , write ):
236257 if self ._expand :
237258 if self ._indent_per_level > 0 :
@@ -303,13 +324,14 @@ def _pprint_ordered_dict(self, object, stream, indent, allowance, context, level
303324 return
304325 cls = object .__class__
305326 stream .write (cls .__name__ + '(' )
306- self ._format (
327+ self ._format_child (
307328 list (object .items ()),
308329 stream ,
309330 self ._child_indent (indent , len (cls .__name__ ) + 1 ),
310331 allowance + 1 ,
311332 context ,
312333 level ,
334+ len (cls .__name__ ) + 1 ,
313335 )
314336 stream .write (')' )
315337
@@ -498,13 +520,14 @@ def _pprint_bytearray(self, object, stream, indent, allowance, context, level):
498520
499521 def _pprint_mappingproxy (self , object , stream , indent , allowance , context , level ):
500522 stream .write ('mappingproxy(' )
501- self ._format (
523+ self ._format_child (
502524 object .copy (),
503525 stream ,
504526 self ._child_indent (indent , 13 ),
505527 allowance + 1 ,
506528 context ,
507529 level ,
530+ 13 ,
508531 )
509532 stream .write (')' )
510533
@@ -540,13 +563,14 @@ def _format_dict_items(self, items, stream, indent, allowance, context,
540563 rep = self ._repr (key , context , level )
541564 write (rep )
542565 write (': ' )
543- self ._format (
566+ self ._format_child (
544567 ent ,
545568 stream ,
546569 self ._child_indent (indent , len (rep ) + 2 ),
547570 allowance if last else 1 ,
548571 context ,
549572 level ,
573+ len (rep ) + 2 ,
550574 )
551575 if not last :
552576 write (delimnl )
@@ -566,13 +590,14 @@ def _format_namespace_items(self, items, stream, indent, allowance, context, lev
566590 # recursive dataclass repr.
567591 write ("..." )
568592 else :
569- self ._format (
593+ self ._format_child (
570594 ent ,
571595 stream ,
572596 self ._child_indent (indent , len (key ) + 1 ),
573597 allowance if last else 1 ,
574598 context ,
575599 level ,
600+ len (key ) + 1 ,
576601 )
577602 if not last :
578603 write (delimnl )
0 commit comments