Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to have 2 actions on argparse argument?

like the title says, I have a parser that has to do 2 things on an argument,

  1. it has to append a const to a list (a list that gives the program all the functions it has to process)
  2. it has to add the value after this argument to a variable, so it can be used later

some code of the parser (will fail, as defining 2 times '-copy' wont work:

parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter, description="""some help text""")
# ... more arguments, but not a problem
parser.add_argument('-ls','--list',action='append_const', dest='tasks',const=ls, help='outputs the filelocation if match was found')
parser.add_argument('-copy', action='append_const', dest='tasks',const=copy, help='copies the file to the given location if a match was found')
parser.add_argument('-copy', dest='copyLocation', help='outputs the filelocation if match was found')

anyone an idea of how to work around this and make the -copy argument do both a store and a append_const?

I know I could just 'postprocess' the args and check if there is a -copy in it, and if so then add the function copy to the list tasks. But this seams like a workaround, so I hoped there is a better way of doing things without postprocessing the arguments.

like image 465
Joris D R. Avatar asked Oct 25 '25 15:10

Joris D R.


1 Answers

thanks to the comment on custom actions I found a nice way of adding this :)

#custom action for store and append_const
class StoreValueAndAppendConst(argparse.Action):
    def __init__(self, option_strings, dest, nargs=None, **kwargs):
        if nargs is not None:
            raise ValueError("nargs not allowed")
        if "task" in kwargs:
            self.task = kwargs["task"]
            del kwargs["task"]
        super(StoreValueAndAppendConst, self).__init__(option_strings, dest, **kwargs)
    def __call__(self, parser, namespace, values, option_string=None):
        #add the task to the list of tasks.
        if not namespace.tasks:
            namespace.tasks = []
        namespace.tasks.append(self.task)
        setattr(namespace, self.dest, values) #do the normal store

and the actually calling changes into:

parser.add_argument('-copy', action=StoreValueAndAppendConst, dest='copy', task=copy, help='outputs the filelocation if match was found')

I might be able to make the custom function more generic, but this is enough for this case.

like image 167
Joris D R. Avatar answered Oct 28 '25 05:10

Joris D R.



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!