Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Lib/argparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -1959,7 +1959,9 @@ def add_subparsers(self, **kwargs):
# prog defaults to the usage message of this parser, skipping
# optional arguments and with no "usage:" prefix
if kwargs.get('prog') is None:
formatter = self._get_formatter()
# Create formatter without color to avoid storing ANSI codes in prog
formatter = self.formatter_class(prog=self.prog)
formatter._set_color(False)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just double checking, sub-commands still get correctly colorized later on, yeah? Before they were just double colored?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that's right.

positionals = self._get_positional_actions()
groups = self._mutually_exclusive_groups
formatter.add_usage(None, positionals, groups, '')
Expand Down
13 changes: 13 additions & 0 deletions Lib/test/test_argparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -7128,7 +7128,9 @@ class TestColorized(TestCase):
def setUp(self):
super().setUp()
# Ensure color even if ran with NO_COLOR=1
original_can_colorize = _colorize.can_colorize
_colorize.can_colorize = lambda *args, **kwargs: True
self.addCleanup(setattr, _colorize, 'can_colorize', original_can_colorize)
self.theme = _colorize.get_theme(force_color=True).argparse

def test_argparse_color(self):
Expand Down Expand Up @@ -7355,6 +7357,17 @@ def __init__(self, prog):
{short_b}+f{reset}, {long_b}++foo{reset} {label_b}FOO{reset} foo help
'''))

def test_subparser_prog_is_stored_without_color(self):
parser = argparse.ArgumentParser(prog='complex', color=True)
sub = parser.add_subparsers(dest='command')
demo_parser = sub.add_parser('demo')

self.assertNotIn('\x1b[', demo_parser.prog)

demo_parser.color = False
help_text = demo_parser.format_help()
self.assertNotIn('\x1b[', help_text)


class TestModule(unittest.TestCase):
def test_deprecated__version__(self):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Prevent premature colorization of subparser ``prog`` in :meth:`argparse.ArgumentParser.add_subparsers` to respect color environment variable changes after parser creation.
Loading