33
44import re as _re
55import sys as _sys
6- import log21 as _log21
76import argparse as _argparse
8-
7+ from typing import Mapping as _Mapping , Optional as _Optional
98from gettext import gettext as _gettext
109from textwrap import TextWrapper as _TextWrapper
11- from typing import Mapping as _Mapping , Optional as _Optional
1210
11+ import log21 as _log21
1312from log21 .Colors import get_colors as _gc
1413from log21 .Formatters import DecolorizingFormatter as _Formatter
1514
16- __all__ = ['ColorizingArgumentParser' , 'ColorizingHelpFormatter' , 'ColorizingTextWrapper' ]
15+ __all__ = [
16+ 'ColorizingArgumentParser' , 'ColorizingHelpFormatter' , 'ColorizingTextWrapper'
17+ ]
1718
1819
1920class ColorizingHelpFormatter (_argparse .HelpFormatter ):
20- def __init__ (self , prog , indent_increment = 2 , max_help_position = 24 , width = None ,
21- colors : _Optional [_Mapping [str , str ]] = None ):
21+
22+ def __init__ (
23+ self ,
24+ prog ,
25+ indent_increment = 2 ,
26+ max_help_position = 24 ,
27+ width = None ,
28+ colors : _Optional [_Mapping [str , str ]] = None
29+ ):
2230 super ().__init__ (prog , indent_increment , max_help_position , width )
23-
31+
2432 self .colors = {
2533 'usage' : 'Cyan' ,
2634 'brackets' : 'LightRed' ,
@@ -39,6 +47,7 @@ def __init__(self, prog, indent_increment=2, max_help_position=24, width=None,
3947 self .colors [key ] = value
4048
4149 class _Section (object ):
50+
4251 def __init__ (self , formatter , parent , heading = None ):
4352 self .formatter = formatter
4453 self .parent = parent
@@ -67,30 +76,36 @@ def format_help(self):
6776 heading = ''
6877
6978 # join the section-initial newline, the heading and the help
70- return join (['\n ' , heading , _gc (self .formatter .colors ['help' ]), item_help , '\n ' ])
79+ return join (
80+ ['\n ' , heading ,
81+ _gc (self .formatter .colors ['help' ]), item_help , '\n ' ]
82+ )
7183
7284 def _add_item (self , func , args ):
7385 self ._current_section .items .append ((func , args ))
7486
7587 def _fill_text (self , text , width , indent ):
7688 text = self ._whitespace_matcher .sub (' ' , text ).strip ()
77- return ColorizingTextWrapper (width = width , initial_indent = indent , subsequent_indent = indent ).fill (text )
89+ return ColorizingTextWrapper (
90+ width = width , initial_indent = indent , subsequent_indent = indent
91+ ).fill (text )
7892
7993 def _split_lines (self , text , width ):
8094 text = self ._whitespace_matcher .sub (' ' , text ).strip ()
8195 return ColorizingTextWrapper (width = width ).wrap (text )
8296
8397 def start_section (self , heading ):
8498 self ._indent ()
85- section = self ._Section (self , self ._current_section ,
86- _gc (self .colors ['section headers' ]) + str (heading ) + '\033 [0m' )
99+ section = self ._Section (
100+ self , self ._current_section ,
101+ _gc (self .colors ['section headers' ]) + str (heading ) + '\033 [0m'
102+ )
87103 self ._add_item (section .format_help , [])
88104 self ._current_section = section
89105
90106 def _format_action (self , action ):
91107 # determine the required width and the entry label
92- help_position = min (self ._action_max_length + 2 ,
93- self ._max_help_position )
108+ help_position = min (self ._action_max_length + 2 , self ._max_help_position )
94109 help_width = max (self ._width - help_position , 11 )
95110 action_width = help_position - self ._current_indent - 2
96111 action_header = _gc ('rst' ) + self ._format_action_invocation (action )
@@ -101,7 +116,9 @@ def _format_action(self, action):
101116 action_header = self ._current_indent * ' ' + action_header + '\n '
102117 # short action name; start on the same line and pad two spaces
103118 elif len (action_header ) <= action_width :
104- action_header = '%*s%-*s ' % (self ._current_indent , '' , action_width , action_header )
119+ action_header = '%*s%-*s ' % (
120+ self ._current_indent , '' , action_width , action_header
121+ )
105122 # long action name; start on the next line
106123 else :
107124 action_header = self ._current_indent * ' ' + action_header + '\n '
@@ -181,7 +198,8 @@ def get_lines(parts, indent, prefix=None):
181198 else :
182199 line_len = len (indent ) - 1
183200 for part in parts :
184- if line_len + 1 + len (_Formatter .decolorize (part )) > text_width and line :
201+ if line_len + 1 + len (_Formatter .decolorize (part )
202+ ) > text_width and line :
185203 lines .append (indent + ' ' .join (line ))
186204 line = []
187205 line_len = len (indent ) - 1
@@ -297,13 +315,15 @@ def _format_actions_usage(self, actions: list, groups):
297315 else :
298316 default = self ._get_default_metavar_for_optional (action )
299317 args_string = self ._format_args (action , default )
300- part = _gc (self .colors ['switches' ]) + '%s %s%s' % (option_string , _gc (self .colors ['values' ]),
301- args_string )
318+ part = _gc (self .colors ['switches' ]) + '%s %s%s' % (
319+ option_string , _gc (self .colors ['values' ]), args_string
320+ )
302321
303322 # make it look optional if it's not required or in a group
304323 if not action .required and action not in group_actions :
305324 part = _gc (self .colors ['brackets' ]) + '[' + part + _gc (
306- self .colors ['brackets' ]) + ']\033 [0m'
325+ self .colors ['brackets' ]
326+ ) + ']\033 [0m'
307327
308328 # add the action string to the list
309329 parts .append (part )
@@ -348,8 +368,10 @@ def _format_action_invocation(self, action):
348368 default = self ._get_default_metavar_for_optional (action )
349369 args_string = self ._format_args (action , default )
350370 for option_string in action .option_strings :
351- parts .append (_gc (self .colors ['switches' ]) + '%s %s%s' % (option_string , _gc (self .colors ['values' ]),
352- args_string ))
371+ parts .append (
372+ _gc (self .colors ['switches' ]) + '%s %s%s' %
373+ (option_string , _gc (self .colors ['values' ]), args_string )
374+ )
353375
354376 return _gc (self .colors ['commas' ]) + ', ' .join (parts )
355377
@@ -368,7 +390,7 @@ def format(tuple_size):
368390 if isinstance (result , tuple ):
369391 return result
370392 else :
371- return (result ,) * tuple_size
393+ return (result , ) * tuple_size
372394
373395 return format
374396
@@ -421,7 +443,8 @@ def _wrap_chunks(self, chunks): # noqa: C901
421443
422444 # First chunk on the line is whitespace -- drop it, unless this
423445 # is the very beginning of the text (i.e. no lines started yet).
424- if self .drop_whitespace and _Formatter .decolorize (chunks [- 1 ]).strip () == '' and lines :
446+ if self .drop_whitespace and _Formatter .decolorize (chunks [- 1 ]
447+ ).strip () == '' and lines :
425448 del chunks [- 1 ]
426449
427450 while chunks :
@@ -444,24 +467,23 @@ def _wrap_chunks(self, chunks): # noqa: C901
444467 current_len = sum (map (len , current_line ))
445468
446469 # If the last chunk on this line is all whitespace, drop it.
447- if self .drop_whitespace and current_line and _Formatter .decolorize (current_line [- 1 ]).strip () == '' :
470+ if self .drop_whitespace and current_line and _Formatter .decolorize (
471+ current_line [- 1 ]).strip () == '' :
448472 current_len -= len (_Formatter .decolorize (current_line [- 1 ]))
449473 del current_line [- 1 ]
450474
451475 if current_line :
452- if (self .max_lines is None or
453- len (lines ) + 1 < self .max_lines or
454- (not chunks or
455- self .drop_whitespace and
456- len (chunks ) == 1 and
457- not chunks [0 ].strip ()) and current_len <= width ):
476+ if (self .max_lines is None or len (lines ) + 1 < self .max_lines
477+ or (not chunks or self .drop_whitespace and len (chunks ) == 1
478+ and not chunks [0 ].strip ()) and current_len <= width ):
458479 # Convert current line back to a string and store it in
459480 # list of all lines (return value).
460481 lines .append (indent + '' .join (current_line ))
461482 else :
462483 while current_line :
463- if _Formatter .decolorize (current_line [- 1 ]).strip () and current_len + len (
464- self .placeholder ) <= width :
484+ if _Formatter .decolorize (
485+ current_line [- 1 ]
486+ ).strip () and current_len + len (self .placeholder ) <= width :
465487 current_line .append (self .placeholder )
466488 lines .append (indent + '' .join (current_line ))
467489 break
@@ -481,7 +503,13 @@ def _wrap_chunks(self, chunks): # noqa: C901
481503
482504
483505class ColorizingArgumentParser (_argparse .ArgumentParser ):
484- def __init__ (self , formatter_class = ColorizingHelpFormatter , colors : _Optional [_Mapping [str , str ]] = None , ** kwargs ):
506+
507+ def __init__ (
508+ self ,
509+ formatter_class = ColorizingHelpFormatter ,
510+ colors : _Optional [_Mapping [str , str ]] = None ,
511+ ** kwargs
512+ ):
485513 self .logger = _log21 .Logger ('ArgumentParser' )
486514 self .colors = colors
487515 super ().__init__ (formatter_class = formatter_class , ** kwargs )
@@ -501,7 +529,12 @@ def exit(self, status=0, message=None):
501529 def error (self , message ):
502530 self .print_usage (_sys .stderr )
503531 args = {'prog' : self .prog , 'message' : message }
504- self .exit (2 , _gettext (f'%(prog)s: { _gc ("r" )} error{ _gc ("lr" )} :{ _gc ("rst" )} %(message)s\n ' ) % args )
532+ self .exit (
533+ 2 ,
534+ _gettext (
535+ f'%(prog)s: { _gc ("r" )} error{ _gc ("lr" )} :{ _gc ("rst" )} %(message)s\n '
536+ ) % args
537+ )
505538
506539 def _get_formatter (self ):
507540 if hasattr (self .formatter_class , 'colors' ):
0 commit comments