From 5c4080a1083d5bf910d9981db59c27ec627c7332 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Salgado Date: Sat, 19 Jul 2025 14:38:21 +0200 Subject: [PATCH 1/7] Default to color help in argparse --- Lib/argparse.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/argparse.py b/Lib/argparse.py index 83258cf3e0f37d..169b442e238a35 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -167,7 +167,7 @@ def __init__( indent_increment=2, max_help_position=24, width=None, - color=False, + color=True, ): # default setting for width if width is None: From f93920d098c24d6977ef0e71ca7dbc0bdfc17f8e Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sat, 19 Jul 2025 16:09:38 +0200 Subject: [PATCH 2/7] Default to color help in argparse --- Lib/argparse.py | 4 ++-- Lib/test/test_argparse.py | 21 ++++++++++++++++++++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/Lib/argparse.py b/Lib/argparse.py index 169b442e238a35..2144c81886ad19 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -1231,7 +1231,7 @@ def __init__(self, self._name_parser_map = {} self._choices_actions = [] self._deprecated = set() - self._color = False + self._color = True super(_SubParsersAction, self).__init__( option_strings=option_strings, @@ -1878,7 +1878,7 @@ def __init__(self, exit_on_error=True, *, suggest_on_error=False, - color=False, + color=True, ): superinit = super(ArgumentParser, self).__init__ superinit(description=description, diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index ddd48b1bc0c56f..7e356d3ae3fdd1 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -18,7 +18,11 @@ import warnings from enum import StrEnum -from test.support import captured_stderr +from test.support import ( + captured_stderr, + force_not_colorized, + force_not_colorized_test_class, +) from test.support import import_helper from test.support import os_helper from test.support import script_helper @@ -1007,6 +1011,7 @@ def test_parse_enum_value(self): args = parser.parse_args(['--color', 'red']) self.assertEqual(args.color, self.Color.RED) + @force_not_colorized def test_help_message_contains_enum_choices(self): parser = argparse.ArgumentParser() parser.add_argument('--color', choices=self.Color, help='Choose a color') @@ -2403,6 +2408,7 @@ def test_modified_invalid_action(self): # Subparsers tests # ================ +@force_not_colorized_test_class class TestAddSubparsers(TestCase): """Test the add_subparsers method""" @@ -3009,6 +3015,7 @@ def test_nested_argument_group(self): # Parent parser tests # =================== +@force_not_colorized_test_class class TestParentParsers(TestCase): """Tests that parsers can be created with parent parsers""" @@ -3216,6 +3223,7 @@ def test_mutex_groups_parents(self): # Mutually exclusive group tests # ============================== +@force_not_colorized_test_class class TestMutuallyExclusiveGroupErrors(TestCase): def test_invalid_add_argument_group(self): @@ -3344,21 +3352,25 @@ def test_successes_when_required(self): actual_ns = parse_args(args_string.split()) self.assertEqual(actual_ns, expected_ns) + @force_not_colorized def test_usage_when_not_required(self): format_usage = self.get_parser(required=False).format_usage expected_usage = self.usage_when_not_required self.assertEqual(format_usage(), textwrap.dedent(expected_usage)) + @force_not_colorized def test_usage_when_required(self): format_usage = self.get_parser(required=True).format_usage expected_usage = self.usage_when_required self.assertEqual(format_usage(), textwrap.dedent(expected_usage)) + @force_not_colorized def test_help_when_not_required(self): format_help = self.get_parser(required=False).format_help help = self.usage_when_not_required + self.help self.assertEqual(format_help(), textwrap.dedent(help)) + @force_not_colorized def test_help_when_required(self): format_help = self.get_parser(required=True).format_help help = self.usage_when_required + self.help @@ -4030,11 +4042,13 @@ def _test(self, tester, parser_text): tester.maxDiff = None tester.assertEqual(expected_text, parser_text) + @force_not_colorized def test_format(self, tester): parser = self._get_parser(tester) format = getattr(parser, 'format_%s' % self.func_suffix) self._test(tester, format()) + @force_not_colorized def test_print(self, tester): parser = self._get_parser(tester) print_ = getattr(parser, 'print_%s' % self.func_suffix) @@ -4047,6 +4061,7 @@ def test_print(self, tester): setattr(sys, self.std_name, old_stream) self._test(tester, parser_text) + @force_not_colorized def test_print_file(self, tester): parser = self._get_parser(tester) print_ = getattr(parser, 'print_%s' % self.func_suffix) @@ -4788,6 +4803,7 @@ class TestHelpUsageMetavarsSpacesParentheses(HelpTestCase): version = '' +@force_not_colorized_test_class class TestHelpUsageNoWhitespaceCrash(TestCase): def test_all_suppressed_mutex_followed_by_long_arg(self): @@ -5469,6 +5485,7 @@ def custom_type(string): version = '' +@force_not_colorized_test_class class TestHelpCustomHelpFormatter(TestCase): maxDiff = None @@ -5765,6 +5782,7 @@ def test_conflict_error(self): self.assertRaises(argparse.ArgumentError, parser.add_argument, '--spam') + @force_not_colorized def test_resolve_error(self): get_parser = argparse.ArgumentParser parser = get_parser(prog='PROG', conflict_handler='resolve') @@ -6829,6 +6847,7 @@ def setUp(self): metavar = '' self.parser.add_argument('--proxy', metavar=metavar) + @force_not_colorized def test_help_with_metavar(self): help_text = self.parser.format_help() self.assertEqual(help_text, textwrap.dedent('''\ From b1ef6402906b2d1ab670021554187c8f06170a26 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sat, 19 Jul 2025 16:21:01 +0200 Subject: [PATCH 3/7] Update docs --- Doc/library/argparse.rst | 20 ++++++------------- Doc/whatsnew/3.14.rst | 9 ++++----- ...-07-19-16-20-54.gh-issue-130645.O-dYcN.rst | 1 + 3 files changed, 11 insertions(+), 19 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2025-07-19-16-20-54.gh-issue-130645.O-dYcN.rst diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index f189f6b8fa8953..87993f88813d4a 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -74,7 +74,7 @@ ArgumentParser objects prefix_chars='-', fromfile_prefix_chars=None, \ argument_default=None, conflict_handler='error', \ add_help=True, allow_abbrev=True, exit_on_error=True, \ - *, suggest_on_error=False, color=False) + *, suggest_on_error=False, color=True) Create a new :class:`ArgumentParser` object. All parameters should be passed as keyword arguments. Each parameter has its own more detailed description @@ -119,7 +119,7 @@ ArgumentParser objects * suggest_on_error_ - Enables suggestions for mistyped argument choices and subparser names (default: ``False``) - * color_ - Allow color output (default: ``False``) + * color_ - Allow color output (default: ``True``) .. versionchanged:: 3.5 *allow_abbrev* parameter was added. @@ -620,27 +620,19 @@ keyword argument:: color ^^^^^ -By default, the help message is printed in plain text. If you want to allow -color in help messages, you can enable it by setting ``color`` to ``True``:: +By default, the help message is printed in color. If you want to plain text +help messages, you can disable it by setting ``color`` to ``False``:: >>> parser = argparse.ArgumentParser(description='Process some integers.', - ... color=True) + ... color=False) >>> parser.add_argument('--action', choices=['sum', 'max']) >>> parser.add_argument('integers', metavar='N', type=int, nargs='+', ... help='an integer for the accumulator') >>> parser.parse_args(['--help']) -Even if a CLI author has enabled color, it can be +Even if a CLI author has not disabled color, it can be :ref:`controlled using environment variables `. -If you're writing code that needs to be compatible with older Python versions -and want to opportunistically use ``color`` when it's available, you -can set it as an attribute after initializing the parser instead of using the -keyword argument:: - - >>> parser = argparse.ArgumentParser(description='Process some integers.') - >>> parser.color = True - .. versionadded:: 3.14 diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index c108a94692dca7..0ec3ed88874efc 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -1204,11 +1204,10 @@ argparse .. _whatsnew314-color-argparse: -* Introduced the optional *color* parameter to - :class:`argparse.ArgumentParser`, enabling color for help text. - This can be controlled by :ref:`environment variables - `. Color has also been enabled for help in the - :ref:`stdlib CLIs ` which use :mod:`!argparse`. +* Enable color for help text, which can be disabled with the optional *color* + parameter to :class:`argparse.ArgumentParser`. + This can also be controlled by :ref:`environment variables + `. (Contributed by Hugo van Kemenade in :gh:`130645`.) diff --git a/Misc/NEWS.d/next/Library/2025-07-19-16-20-54.gh-issue-130645.O-dYcN.rst b/Misc/NEWS.d/next/Library/2025-07-19-16-20-54.gh-issue-130645.O-dYcN.rst new file mode 100644 index 00000000000000..bc32482770597b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-07-19-16-20-54.gh-issue-130645.O-dYcN.rst @@ -0,0 +1 @@ +Default to color help in argparse. From dddcd65c04e26d2974e361253b8095e10254ab63 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sat, 19 Jul 2025 16:47:19 +0200 Subject: [PATCH 4/7] Update tests --- Lib/test/test_argparse.py | 2 ++ Lib/test/test_clinic.py | 1 + 2 files changed, 3 insertions(+) diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index 7e356d3ae3fdd1..fc73174d98cd6f 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -6049,6 +6049,7 @@ def test_argument_error(self): class TestArgumentTypeError(TestCase): + @force_not_colorized def test_argument_type_error(self): def spam(string): @@ -7013,6 +7014,7 @@ def test_os_error(self): self.parser.parse_args, ['@no-such-file']) +@force_not_colorized_test_class class TestProgName(TestCase): source = textwrap.dedent('''\ import argparse diff --git a/Lib/test/test_clinic.py b/Lib/test/test_clinic.py index e83114794519d5..b1a81cfc1b124f 100644 --- a/Lib/test/test_clinic.py +++ b/Lib/test/test_clinic.py @@ -2792,6 +2792,7 @@ def test_cli_verbose(self): out = self.expect_success("-v", fn) self.assertEqual(out.strip(), fn) + @support.force_not_colorized def test_cli_help(self): out = self.expect_success("-h") self.assertIn("usage: clinic.py", out) From b5c0d881b497f4e6455cf3fdadcd100eae549077 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sat, 19 Jul 2025 18:19:12 +0300 Subject: [PATCH 5/7] Fix wording MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ɓukasz Langa --- Doc/library/argparse.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index 87993f88813d4a..b80c00e9eecba5 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -620,7 +620,7 @@ keyword argument:: color ^^^^^ -By default, the help message is printed in color. If you want to plain text +By default, the help message is printed in color. If you want plain text help messages, you can disable it by setting ``color`` to ``False``:: >>> parser = argparse.ArgumentParser(description='Process some integers.', From 82c7e2511c631ab9dfb7a031bd078a27296233fa Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Sat, 19 Jul 2025 17:32:07 +0200 Subject: [PATCH 6/7] Improve description of disabling colour support locally vs in the ArgumentParser --- Doc/library/argparse.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index b80c00e9eecba5..ed603171102fe1 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -620,8 +620,11 @@ keyword argument:: color ^^^^^ -By default, the help message is printed in color. If you want plain text -help messages, you can disable it by setting ``color`` to ``False``:: +By default, the help message is printed in color using `ANSI escape sequences +`__. +If you want plain text help messages, you can disable this :ref:`in your local +environment `, or in the argument parser itself +by setting ``color`` to ``False``:: >>> parser = argparse.ArgumentParser(description='Process some integers.', ... color=False) @@ -630,9 +633,6 @@ help messages, you can disable it by setting ``color`` to ``False``:: ... help='an integer for the accumulator') >>> parser.parse_args(['--help']) -Even if a CLI author has not disabled color, it can be -:ref:`controlled using environment variables `. - .. versionadded:: 3.14 From 0abf68e3264d4953517edbd40856805761c5dc15 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Sat, 19 Jul 2025 17:40:47 +0200 Subject: [PATCH 7/7] Add a cross-reference to NEWS --- .../next/Library/2025-07-19-16-20-54.gh-issue-130645.O-dYcN.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2025-07-19-16-20-54.gh-issue-130645.O-dYcN.rst b/Misc/NEWS.d/next/Library/2025-07-19-16-20-54.gh-issue-130645.O-dYcN.rst index bc32482770597b..96e076dfe5bd12 100644 --- a/Misc/NEWS.d/next/Library/2025-07-19-16-20-54.gh-issue-130645.O-dYcN.rst +++ b/Misc/NEWS.d/next/Library/2025-07-19-16-20-54.gh-issue-130645.O-dYcN.rst @@ -1 +1 @@ -Default to color help in argparse. +Enable color help by default in :mod:`argparse`. pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy