hamdanal / rich-argparse

A rich help formatter for argparse
https://pypi.org/project/rich-argparse/
MIT License
129 stars 11 forks source link

Add raise.error as red-bold type #62

Closed ipesanz closed 1 year ago

ipesanz commented 1 year ago

Feature request

I think would be nice if the parser.error can be of type:

error_message = f"[bold red]Error:[/bold red] {error}"
console.print(box(error_message, style="bold red"), highlight=False)

Context:

def parse_arguments():
    parser = argparse.ArgumentParser(formatter_class=RichHelpFormatter, (...))
    # adding argument
    parser.add_argument('-a','--auto', action='store_true', help='Do something in automatic mode (...)')
    . . .
    args = parser.parse_args()
    # Validation:
    ## check emptyargs
    if len(sys.argv) == 1:
        raise parser.error('This program needs at least one argument to run. Use -h to check for help')
   . . . 

Desired state: That the messages from raise.error would be in some red-color using the default RichHelpFormatter. The traceback exception should be fixed (reason of the request) image

ipesanz commented 1 year ago

Tests done:

import argparse
from rich.console import Console
from rich import print, box

console = Console()

def custom_error_handler(error):
    error_message = f"[bold red]Error:[/bold red] {error}"
    console.print(box(error_message, style="bold red"), highlight=False)

parser = argparse.ArgumentParser()
parser.error = custom_error_handler

parser.add_argument("foo", help="foo help")
parser.add_argument("bar", help="bar help")
args = parser.parse_args()
if len(sys.argv) == 1:
    raise parser.error('This program needs at least one argument to run. Use -h to check for help')

My initial definition with raise parser.error work at the beginning, showing the message in plain text and showing the help. I think is a common practice somewhere documented in internet

I didn't came up with a better implementation, as any workaround would imply import directly the class: ArgumentError or do dirty tricks in the code.

Questions:

  1. Is legit the request? Does it make sense? In my opinion, and within the context of enhancing the output of argparse with Rich, yes
  2. Which should be the appropiate way to achieve this functionality? I can give some extra tries, but they will be dirty as I'm lacking of general python knowledge to make a MR with a feature developed on my own #sorry
hamdanal commented 1 year ago

That the messages from raise.error would be in some red-color using the default RichHelpFormatter

Unfortunately this is not possible in rich-argparse.RichHelpFormatter does not have access to the parser object that has the .error() method.

  1. Is legit the request? Does it make sense? In my opinion, and within the context of enhancing the output of argparse with Rich, yes

It is a legit request but unfortunately it is out of the scope of this library. This library only provides help formatter implementation, it does not replace everything in argparse. Until/If argparse changes to make the formatter aware of the parser, this will not be feasible.

  1. Which should be the appropiate way to achieve this functionality?

The only way possible way is to handle this after argument parsing.

import argparse
import sys

import rich
from rich_argparse import RichHelpFormatter

parser = argparse.ArgumentParser(formatter_class=RichHelpFormatter)
parser.add_argument("-a", "--auto", action="store_true", help="Do something in automatic mode (...)")
# other arguments here

args = parser.parse_args()

if bad_condition_here:
    parser.print_usage()  # optionally print the short usage (this uses RichHelpFormatter)
    rich.print("Other fancy output")
    sys.exit(1)

Unrelated to your request but I'll point this out because it might be helpful