File tree Expand file tree Collapse file tree 2 files changed +39
-4
lines changed
Expand file tree Collapse file tree 2 files changed +39
-4
lines changed Original file line number Diff line number Diff line change @@ -688,11 +688,30 @@ def _expand_help(self, action):
688688 params [name ] = value .__name__
689689 if params .get ('choices' ) is not None :
690690 params ['choices' ] = ', ' .join (map (str , params ['choices' ]))
691- # Before interpolating, wrap the values with color codes
691+
692692 t = self ._theme
693- for name , value in params .items ():
694- params [name ] = f"{ t .interpolated_value } { value } { t .reset } "
695- return help_string % params
693+
694+ if not t .reset :
695+ return help_string % params
696+
697+ # Format first to preserve types for specifiers, like %x that require int.
698+ def colorize (match ):
699+ spec , name = match .group (0 , 1 )
700+ if spec == '%%' :
701+ return '%'
702+ if name in params :
703+ formatted = spec % {name : params [name ]}
704+ return f'{ t .interpolated_value } { formatted } { t .reset } '
705+ return spec
706+
707+ # Match %% (literal %) or %(name)... format specifiers
708+ result = _re .sub (r'%%|%\((\w+)\)[^a-z]*[a-z]' , colorize ,
709+ help_string , flags = _re .IGNORECASE )
710+
711+ # Check for invalid/unmatched % specifiers
712+ if '%' in result :
713+ raise ValueError (f"invalid format specifier in: { help_string !r} " )
714+ return result
696715
697716 def _iter_indented_subactions (self , action ):
698717 try :
Original file line number Diff line number Diff line change @@ -7663,6 +7663,22 @@ def test_backtick_markup_special_regex_chars(self):
76637663 help_text = parser .format_help ()
76647664 self .assertIn (f'{ prog_extra } grep "foo.*bar" | sort{ reset } ' , help_text )
76657665
7666+ def test_help_with_format_specifiers (self ):
7667+ # GH-142950: format specifiers like %x should work with color=True
7668+ parser = argparse .ArgumentParser (prog = 'PROG' , color = True )
7669+ parser .add_argument ('--hex' , type = int , default = 255 ,
7670+ help = 'hex: %(default)x' )
7671+ parser .add_argument ('--str' , default = 'test' ,
7672+ help = 'str: %(default)s' )
7673+
7674+ help_text = parser .format_help ()
7675+
7676+ interp = self .theme .interpolated_value
7677+ reset = self .theme .reset
7678+
7679+ self .assertIn (f'hex: { interp } ff{ reset } ' , help_text )
7680+ self .assertIn (f'str: { interp } test{ reset } ' , help_text )
7681+
76667682 def test_print_help_uses_target_file_for_color_decision (self ):
76677683 parser = argparse .ArgumentParser (prog = 'PROG' , color = True )
76687684 parser .add_argument ('--opt' )
You can’t perform that action at this time.
0 commit comments