https://github.com/python/cpython/commit/8b669d54c367ac2029ee48296c2e00384308ffa8
commit: 8b669d54c367ac2029ee48296c2e00384308ffa8
branch: main
author: Savannah Ostrowski <[email protected]>
committer: savannahostrowski <[email protected]>
date: 2025-12-12T20:08:19Z
summary:

GH-142389: Add backtick markup support in description and epilog (#142390)

files:
A Misc/NEWS.d/next/Library/2025-12-07-22-13-28.gh-issue-142389.J9v904.rst
M Doc/library/argparse.rst
M Doc/whatsnew/3.15.rst
M Lib/argparse.py
M Lib/test/test_argparse.py

diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst
index d50ec34e54d710..70dd342ab66a47 100644
--- a/Doc/library/argparse.rst
+++ b/Doc/library/argparse.rst
@@ -645,6 +645,27 @@ are set.
 
 .. versionadded:: 3.14
 
+To highlight inline code in your description or epilog text, you can use
+backticks::
+
+   >>> parser = argparse.ArgumentParser(
+   ...     formatter_class=argparse.RawDescriptionHelpFormatter,
+   ...     epilog='''Examples:
+   ...   `python -m myapp --verbose`
+   ...   `python -m myapp --config settings.json`
+   ... ''')
+
+When colors are enabled, the text inside backticks will be displayed in a
+distinct color to help examples stand out. When colors are disabled, backticks
+are preserved as-is, which is readable in plain text.
+
+.. note::
+
+   Backtick markup only applies to description and epilog text. It does not
+   apply to individual argument ``help`` strings.
+
+.. versionadded:: 3.15
+
 
 The add_argument() method
 -------------------------
diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst
index 1d8b838cd2e7f0..afefcc15ab2d55 100644
--- a/Doc/whatsnew/3.15.rst
+++ b/Doc/whatsnew/3.15.rst
@@ -423,6 +423,10 @@ argparse
   default to ``True``. This enables suggestions for mistyped arguments by 
default.
   (Contributed by Jakob Schluse in :gh:`140450`.)
 
+* Added backtick markup support in description and epilog text to highlight
+  inline code when color output is enabled.
+  (Contributed by Savannah Ostrowski in :gh:`142390`.)
+
 calendar
 --------
 
diff --git a/Lib/argparse.py b/Lib/argparse.py
index ee7ebc4696a0f7..633fec69ea4615 100644
--- a/Lib/argparse.py
+++ b/Lib/argparse.py
@@ -517,7 +517,27 @@ def _format_text(self, text):
             text = text % dict(prog=self._prog)
         text_width = max(self._width - self._current_indent, 11)
         indent = ' ' * self._current_indent
-        return self._fill_text(text, text_width, indent) + '\n\n'
+        text = self._fill_text(text, text_width, indent)
+        text = self._apply_text_markup(text)
+        return text + '\n\n'
+
+    def _apply_text_markup(self, text):
+        """Apply color markup to text.
+
+        Supported markup:
+          `...` - inline code (rendered with prog_extra color)
+
+        When colors are disabled, backticks are preserved as-is.
+        """
+        t = self._theme
+        if not t.reset:
+            return text
+        text = _re.sub(
+            r'`([^`]+)`',
+            rf'{t.prog_extra}\1{t.reset}',
+            text,
+        )
+        return text
 
     def _format_action(self, action):
         # determine the required width and the entry label
diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py
index 0f93e8ea740770..758af98d5cb046 100644
--- a/Lib/test/test_argparse.py
+++ b/Lib/test/test_argparse.py
@@ -7568,6 +7568,101 @@ def 
test_error_and_warning_not_colorized_when_disabled(self):
         self.assertNotIn('\x1b[', warn)
         self.assertIn('warning:', warn)
 
+    def test_backtick_markup_in_epilog(self):
+        parser = argparse.ArgumentParser(
+            prog='PROG',
+            color=True,
+            epilog='Example: `python -m myapp --verbose`',
+        )
+
+        prog_extra = self.theme.prog_extra
+        reset = self.theme.reset
+
+        help_text = parser.format_help()
+        self.assertIn(f'Example: {prog_extra}python -m myapp --verbose{reset}',
+                      help_text)
+        self.assertNotIn('`', help_text)
+
+    def test_backtick_markup_in_description(self):
+        parser = argparse.ArgumentParser(
+            prog='PROG',
+            color=True,
+            description='Run `python -m myapp` to start.',
+        )
+
+        prog_extra = self.theme.prog_extra
+        reset = self.theme.reset
+
+        help_text = parser.format_help()
+        self.assertIn(f'Run {prog_extra}python -m myapp{reset} to start.',
+                      help_text)
+
+    def test_backtick_markup_multiple(self):
+        parser = argparse.ArgumentParser(
+            prog='PROG',
+            color=True,
+            epilog='Try `app run` or `app test`.',
+        )
+
+        prog_extra = self.theme.prog_extra
+        reset = self.theme.reset
+
+        help_text = parser.format_help()
+        self.assertIn(f'{prog_extra}app run{reset}', help_text)
+        self.assertIn(f'{prog_extra}app test{reset}', help_text)
+
+    def test_backtick_markup_not_applied_when_color_disabled(self):
+        # When color is disabled, backticks are preserved as-is
+        parser = argparse.ArgumentParser(
+            prog='PROG',
+            color=False,
+            epilog='Example: `python -m myapp`',
+        )
+
+        help_text = parser.format_help()
+        self.assertIn('`python -m myapp`', help_text)
+        self.assertNotIn('\x1b[', help_text)
+
+    def test_backtick_markup_with_format_string(self):
+        parser = argparse.ArgumentParser(
+            prog='myapp',
+            color=True,
+            epilog='Run `%(prog)s --help` for more info.',
+        )
+
+        prog_extra = self.theme.prog_extra
+        reset = self.theme.reset
+
+        help_text = parser.format_help()
+        self.assertIn(f'{prog_extra}myapp --help{reset}', help_text)
+
+    def test_backtick_markup_in_subparser(self):
+        parser = argparse.ArgumentParser(prog='PROG', color=True)
+        subparsers = parser.add_subparsers()
+        sub = subparsers.add_parser(
+            'sub',
+            description='Run `PROG sub --foo` to start.',
+        )
+
+        prog_extra = self.theme.prog_extra
+        reset = self.theme.reset
+
+        help_text = sub.format_help()
+        self.assertIn(f'{prog_extra}PROG sub --foo{reset}', help_text)
+
+    def test_backtick_markup_special_regex_chars(self):
+        parser = argparse.ArgumentParser(
+            prog='PROG',
+            color=True,
+            epilog='`grep "foo.*bar" | sort`',
+        )
+
+        prog_extra = self.theme.prog_extra
+        reset = self.theme.reset
+
+        help_text = parser.format_help()
+        self.assertIn(f'{prog_extra}grep "foo.*bar" | sort{reset}', help_text)
+
     def test_print_help_uses_target_file_for_color_decision(self):
         parser = argparse.ArgumentParser(prog='PROG', color=True)
         parser.add_argument('--opt')
diff --git 
a/Misc/NEWS.d/next/Library/2025-12-07-22-13-28.gh-issue-142389.J9v904.rst 
b/Misc/NEWS.d/next/Library/2025-12-07-22-13-28.gh-issue-142389.J9v904.rst
new file mode 100644
index 00000000000000..44e9cea7b54a8f
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-12-07-22-13-28.gh-issue-142389.J9v904.rst
@@ -0,0 +1 @@
+Add backtick markup support in :mod:`argparse` description and epilog text to 
highlight inline code when color output is enabled.

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to