4444
4545
4646def pprint (object , stream = None , indent = 1 , width = 80 , depth = None , * ,
47- compact = False , sort_dicts = True , underscore_numbers = False ):
47+ compact = False , sort_dicts = True , underscore_numbers = False , block_style = False ):
4848 """Pretty-print a Python object to a stream [default is sys.stdout]."""
4949 printer = PrettyPrinter (
5050 stream = stream , indent = indent , width = width , depth = depth ,
5151 compact = compact , sort_dicts = sort_dicts ,
52- underscore_numbers = underscore_numbers )
52+ underscore_numbers = underscore_numbers , block_style = block_style )
5353 printer .pprint (object )
5454
5555
5656def pformat (object , indent = 1 , width = 80 , depth = None , * ,
57- compact = False , sort_dicts = True , underscore_numbers = False ):
57+ compact = False , sort_dicts = True , underscore_numbers = False , block_style = False ):
5858 """Format a Python object into a pretty-printed representation."""
5959 return PrettyPrinter (indent = indent , width = width , depth = depth ,
6060 compact = compact , sort_dicts = sort_dicts ,
61- underscore_numbers = underscore_numbers ).pformat (object )
61+ underscore_numbers = underscore_numbers , block_style = block_style ).pformat (object )
6262
6363
6464def pp (object , * args , sort_dicts = False , ** kwargs ):
@@ -111,7 +111,7 @@ def _safe_tuple(t):
111111
112112class PrettyPrinter :
113113 def __init__ (self , indent = 1 , width = 80 , depth = None , stream = None , * ,
114- compact = False , sort_dicts = True , underscore_numbers = False ):
114+ compact = False , sort_dicts = True , underscore_numbers = False , block_style = False ):
115115 """Handle pretty printing operations onto a stream using a set of
116116 configured parameters.
117117
@@ -137,6 +137,11 @@ def __init__(self, indent=1, width=80, depth=None, stream=None, *,
137137 underscore_numbers
138138 If true, digit groups are separated with underscores.
139139
140+ block_style
141+ If true, the output will be formatted in a block style similar to
142+ pretty-printed json.dumps() when `indent` is supplied. Incompatible
143+ with compact mode.
144+
140145 """
141146 indent = int (indent )
142147 width = int (width )
@@ -146,6 +151,8 @@ def __init__(self, indent=1, width=80, depth=None, stream=None, *,
146151 raise ValueError ('depth must be > 0' )
147152 if not width :
148153 raise ValueError ('width must be != 0' )
154+ if compact and block_style :
155+ raise ValueError ('compact and block_style are incompatible' )
149156 self ._depth = depth
150157 self ._indent_per_level = indent
151158 self ._width = width
@@ -156,6 +163,7 @@ def __init__(self, indent=1, width=80, depth=None, stream=None, *,
156163 self ._compact = bool (compact )
157164 self ._sort_dicts = sort_dicts
158165 self ._underscore_numbers = underscore_numbers
166+ self ._block_style = bool (block_style )
159167
160168 def pprint (self , object ):
161169 if self ._stream is not None :
@@ -205,24 +213,39 @@ def _format(self, object, stream, indent, allowance, context, level):
205213 return
206214 stream .write (rep )
207215
216+ def _format_block_start (self , start_str , indent ):
217+ if self ._block_style :
218+ return start_str + '\n ' + ' ' * indent
219+ else :
220+ return start_str
221+
222+ def _format_block_end (self , end_str , indent ):
223+ if self ._block_style :
224+ return '\n ' + ' ' * indent + end_str
225+ else :
226+ return end_str
227+
208228 def _pprint_dataclass (self , object , stream , indent , allowance , context , level ):
209229 # Lazy import to improve module import time
210230 from dataclasses import fields as dataclass_fields
211231
212232 cls_name = object .__class__ .__name__
213- indent += len (cls_name ) + 1
233+ indent += len (cls_name ) + 1 if not self . _block_style else self . _indent_per_level
214234 items = [(f .name , getattr (object , f .name )) for f in dataclass_fields (object ) if f .repr ]
215- stream .write (cls_name + '(' )
235+ stream .write (self . _format_block_start ( cls_name + '(' , indent ) )
216236 self ._format_namespace_items (items , stream , indent , allowance , context , level )
217- stream .write (')' )
237+ if self ._block_style :
238+ stream .write ('\n ' )
239+ stream .write (self ._format_block_end (')' , indent - self ._indent_per_level ))
218240
219241 _dispatch = {}
220242
221243 def _pprint_dict (self , object , stream , indent , allowance , context , level ):
222244 write = stream .write
223- write ('{' )
245+ write (self . _format_block_start ( '{' , indent ) )
224246 if self ._indent_per_level > 1 :
225- write ((self ._indent_per_level - 1 ) * ' ' )
247+ indent_adjust = 0 if self ._block_style else - 1
248+ write ((self ._indent_per_level + indent_adjust ) * ' ' )
226249 length = len (object )
227250 if length :
228251 if self ._sort_dicts :
@@ -231,7 +254,7 @@ def _pprint_dict(self, object, stream, indent, allowance, context, level):
231254 items = object .items ()
232255 self ._format_dict_items (items , stream , indent , allowance + 1 ,
233256 context , level )
234- write ('}' )
257+ write (self . _format_block_end ( '}' , indent ) )
235258
236259 _dispatch [dict .__repr__ ] = _pprint_dict
237260
@@ -241,27 +264,28 @@ def _pprint_ordered_dict(self, object, stream, indent, allowance, context, level
241264 return
242265 cls = object .__class__
243266 stream .write (cls .__name__ + '(' )
267+ recursive_indent = indent + len (cls .__name__ ) + 1 if not self ._block_style else indent
244268 self ._format (list (object .items ()), stream ,
245- indent + len ( cls . __name__ ) + 1 , allowance + 1 ,
269+ recursive_indent , allowance + 1 ,
246270 context , level )
247271 stream .write (')' )
248272
249273 _dispatch [_collections .OrderedDict .__repr__ ] = _pprint_ordered_dict
250274
251275 def _pprint_list (self , object , stream , indent , allowance , context , level ):
252- stream .write ('[' )
276+ stream .write (self . _format_block_start ( '[' , indent ) )
253277 self ._format_items (object , stream , indent , allowance + 1 ,
254278 context , level )
255- stream .write (']' )
279+ stream .write (self . _format_block_end ( ']' , indent ) )
256280
257281 _dispatch [list .__repr__ ] = _pprint_list
258282
259283 def _pprint_tuple (self , object , stream , indent , allowance , context , level ):
260- stream .write ('(' )
284+ stream .write (self . _format_block_start ( '(' , indent ) )
261285 endchar = ',)' if len (object ) == 1 else ')'
262286 self ._format_items (object , stream , indent , allowance + len (endchar ),
263287 context , level )
264- stream .write (endchar )
288+ stream .write (self . _format_block_end ( endchar , indent ) )
265289
266290 _dispatch [tuple .__repr__ ] = _pprint_tuple
267291
@@ -271,16 +295,16 @@ def _pprint_set(self, object, stream, indent, allowance, context, level):
271295 return
272296 typ = object .__class__
273297 if typ is set :
274- stream .write ('{' )
298+ stream .write (self . _format_block_start ( '{' , indent ) )
275299 endchar = '}'
276300 else :
277- stream .write (typ .__name__ + '({' )
301+ stream .write (self . _format_block_start ( typ .__name__ + '({' , indent ) )
278302 endchar = '})'
279- indent += len (typ .__name__ ) + 1
303+ indent += len (typ .__name__ ) + 1 if not self . _block_style else 0
280304 object = sorted (object , key = _safe_key )
281305 self ._format_items (object , stream , indent , allowance + len (endchar ),
282306 context , level )
283- stream .write (endchar )
307+ stream .write (self . _format_block_end ( endchar , indent ) )
284308
285309 _dispatch [set .__repr__ ] = _pprint_set
286310 _dispatch [frozenset .__repr__ ] = _pprint_set
@@ -346,32 +370,35 @@ def _pprint_bytes(self, object, stream, indent, allowance, context, level):
346370 return
347371 parens = level == 1
348372 if parens :
349- indent += 1
373+ indent += 1 if not self . _block_style else self . _indent_per_level
350374 allowance += 1
351- write ('(' )
375+ write (self . _format_block_start ( '(' , indent ) )
352376 delim = ''
353377 for rep in _wrap_bytes_repr (object , self ._width - indent , allowance ):
354378 write (delim )
355379 write (rep )
356380 if not delim :
357381 delim = '\n ' + ' ' * indent
358382 if parens :
359- write (')' )
383+ write (self . _format_block_end ( ')' , indent - self . _indent_per_level ) )
360384
361385 _dispatch [bytes .__repr__ ] = _pprint_bytes
362386
363387 def _pprint_bytearray (self , object , stream , indent , allowance , context , level ):
364388 write = stream .write
365- write ('bytearray(' )
366- self ._pprint_bytes (bytes (object ), stream , indent + 10 ,
389+ write (self ._format_block_start ('bytearray(' , indent ))
390+ write (' ' * self ._indent_per_level )
391+ recursive_indent = indent + 10 if not self ._block_style else indent + self ._indent_per_level
392+ self ._pprint_bytes (bytes (object ), stream , recursive_indent ,
367393 allowance + 1 , context , level + 1 )
368- write (')' )
394+ write (self . _format_block_end ( ')' , indent ) )
369395
370396 _dispatch [bytearray .__repr__ ] = _pprint_bytearray
371397
372398 def _pprint_mappingproxy (self , object , stream , indent , allowance , context , level ):
373399 stream .write ('mappingproxy(' )
374- self ._format (object .copy (), stream , indent + 13 , allowance + 1 ,
400+ recursive_indent = indent + 13 if not self ._block_style else indent
401+ self ._format (object .copy (), stream , recursive_indent , allowance + 1 ,
375402 context , level )
376403 stream .write (')' )
377404
@@ -384,11 +411,11 @@ def _pprint_simplenamespace(self, object, stream, indent, allowance, context, le
384411 cls_name = 'namespace'
385412 else :
386413 cls_name = object .__class__ .__name__
387- indent += len (cls_name ) + 1
414+ indent += len (cls_name ) + 1 if not self . _block_style else self . _indent_per_level
388415 items = object .__dict__ .items ()
389- stream .write (cls_name + '(' )
416+ stream .write (self . _format_block_start ( cls_name + '(' , indent ) )
390417 self ._format_namespace_items (items , stream , indent , allowance , context , level )
391- stream .write (')' )
418+ stream .write (self . _format_block_end ( ')' , indent - self . _indent_per_level ) )
392419
393420 _dispatch [_types .SimpleNamespace .__repr__ ] = _pprint_simplenamespace
394421
@@ -403,7 +430,8 @@ def _format_dict_items(self, items, stream, indent, allowance, context,
403430 rep = self ._repr (key , context , level )
404431 write (rep )
405432 write (': ' )
406- self ._format (ent , stream , indent + len (rep ) + 2 ,
433+ recursive_indent = indent + len (rep ) + 2 if not self ._block_style else indent
434+ self ._format (ent , stream , recursive_indent ,
407435 allowance if last else 1 ,
408436 context , level )
409437 if not last :
@@ -422,7 +450,8 @@ def _format_namespace_items(self, items, stream, indent, allowance, context, lev
422450 # recursive dataclass repr.
423451 write ("..." )
424452 else :
425- self ._format (ent , stream , indent + len (key ) + 1 ,
453+ recursive_indent = indent + len (key ) + 1 if not self ._block_style else indent
454+ self ._format (ent , stream , recursive_indent ,
426455 allowance if last else 1 ,
427456 context , level )
428457 if not last :
@@ -432,7 +461,8 @@ def _format_items(self, items, stream, indent, allowance, context, level):
432461 write = stream .write
433462 indent += self ._indent_per_level
434463 if self ._indent_per_level > 1 :
435- write ((self ._indent_per_level - 1 ) * ' ' )
464+ indent_adjust = 0 if self ._block_style else - 1
465+ write ((self ._indent_per_level + indent_adjust ) * ' ' )
436466 delimnl = ',\n ' + ' ' * indent
437467 delim = ''
438468 width = max_width = self ._width - indent + 1
@@ -491,8 +521,11 @@ def _pprint_default_dict(self, object, stream, indent, allowance, context, level
491521 return
492522 rdf = self ._repr (object .default_factory , context , level )
493523 cls = object .__class__
494- indent += len (cls .__name__ ) + 1
495- stream .write ('%s(%s,\n %s' % (cls .__name__ , rdf , ' ' * indent ))
524+ indent += len (cls .__name__ ) + 1 if not self ._block_style else 0
525+ if self ._block_style :
526+ stream .write ('%s(%s, ' % (cls .__name__ , rdf ))
527+ else :
528+ stream .write ('%s(%s,\n %s' % (cls .__name__ , rdf , ' ' * indent ))
496529 self ._pprint_dict (object , stream , indent , allowance + 1 , context , level )
497530 stream .write (')' )
498531
@@ -503,14 +536,15 @@ def _pprint_counter(self, object, stream, indent, allowance, context, level):
503536 stream .write (repr (object ))
504537 return
505538 cls = object .__class__
506- stream .write (cls .__name__ + '({' )
539+ stream .write (self . _format_block_start ( cls .__name__ + '({' , indent ) )
507540 if self ._indent_per_level > 1 :
508541 stream .write ((self ._indent_per_level - 1 ) * ' ' )
509542 items = object .most_common ()
543+ recursive_indent = indent + len (cls .__name__ ) + 1 if not self ._block_style else indent
510544 self ._format_dict_items (items , stream ,
511- indent + len ( cls . __name__ ) + 1 , allowance + 2 ,
545+ recursive_indent , allowance + 2 ,
512546 context , level )
513- stream .write ('})' )
547+ stream .write (self . _format_block_end ( '})' , indent ) )
514548
515549 _dispatch [_collections .Counter .__repr__ ] = _pprint_counter
516550
@@ -519,12 +553,12 @@ def _pprint_chain_map(self, object, stream, indent, allowance, context, level):
519553 stream .write (repr (object ))
520554 return
521555 cls = object .__class__
522- stream .write (cls .__name__ + '(' )
523- indent += len (cls .__name__ ) + 1
556+ stream .write (self . _format_block_start ( cls .__name__ + '(' , indent + self . _indent_per_level ) )
557+ indent += len (cls .__name__ ) + 1 if not self . _block_style else self . _indent_per_level
524558 for i , m in enumerate (object .maps ):
525559 if i == len (object .maps ) - 1 :
526560 self ._format (m , stream , indent , allowance + 1 , context , level )
527- stream .write (')' )
561+ stream .write (self . _format_block_end ( ')' , indent - self . _indent_per_level ) )
528562 else :
529563 self ._format (m , stream , indent , 1 , context , level )
530564 stream .write (',\n ' + ' ' * indent )
@@ -536,18 +570,20 @@ def _pprint_deque(self, object, stream, indent, allowance, context, level):
536570 stream .write (repr (object ))
537571 return
538572 cls = object .__class__
539- stream .write (cls .__name__ + '(' )
540- indent += len (cls .__name__ ) + 1
541- stream .write ('[' )
573+ stream .write (self ._format_block_start (cls .__name__ + '([' , indent ))
574+ indent += len (cls .__name__ ) + 1 if not self ._block_style else 0
542575 if object .maxlen is None :
543576 self ._format_items (object , stream , indent , allowance + 2 ,
544577 context , level )
545- stream .write ('])' )
578+ stream .write (self . _format_block_end ( '])' , indent ) )
546579 else :
547580 self ._format_items (object , stream , indent , 2 ,
548581 context , level )
549582 rml = self ._repr (object .maxlen , context , level )
550- stream .write ('],\n %smaxlen=%s)' % (' ' * indent , rml ))
583+ if self ._block_style :
584+ stream .write ('%s], maxlen=%s)' % ('\n ' + ' ' * indent , rml ))
585+ else :
586+ stream .write ('],\n %smaxlen=%s)' % (' ' * indent , rml ))
551587
552588 _dispatch [_collections .deque .__repr__ ] = _pprint_deque
553589
0 commit comments