Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replacing argument in argparse [closed]

I have a base class I cannot modify (code may have other errors, but please ignore those)

class BaseClass(object):
    def __init__(self):
        self.parser = argparse.ArgumentParser()
        self.parser.add_argument("arg1", choices=("a", "b"))

What I want is to override arg1 as follows

class DerivedClass(BaseClass):
    def __init__(self):
        BaseClass.__init__(self)
        self.parser.add_argument("arg1", choices=("a", "c", "d"))
like image 437
max_max_mir Avatar asked Jul 18 '26 15:07

max_max_mir


1 Answers

If you can't modify the base class implementation, you could reach into the attributes of the parser and modify the specific action you care about. Here's a sketch of code demonstrating just that:

from base import BaseClass


def _modify_choices(parser, dest, choices):
    for action in parser._actions:
        if action.dest == dest:
            action.choices = choices
            return
    else:
        raise AssertionError('argument {} not found'.format(dest))


class MySubClass(BaseClass):
    def __init__(self):
        super(MySubClass, self).__init__()
        _modify_choices(self.parser, 'arg1', ('a', 'b', 'c'))


def main():
    inst = MySubClass()
    inst.parser.parse_args()


if __name__ == '__main__':
    exit(main())

And usage:

$ python subclass.py d
usage: subclass.py [-h] {a,b,c}
subclass.py: error: argument arg1: invalid choice: 'd' (choose from 'a', 'b', 'c')

Note that this reaches into private implementation details (notably ArgumentParser._actions) but otherwise uses public interfaces.

like image 143
Anthony Sottile Avatar answered Jul 20 '26 05:07

Anthony Sottile



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!