I need to implement an ArgParse builder to generate parsers and regarding subparsers and arguments. I created a decorator to declare subparsers as action. Here is the class which contains the decorator:
class Controller(object):
endpoints = None
parser = None
subparsers = None
def __init__(self, endpoint=None):
from src.app.commons.ArgParser import ArgParser
if not self.parser:
self.parser = ArgParser()
# Get all
self.endpoints = utilities.conf_wrapper()
self.mod = endpoint
if not self.subparsers:
self.subparsers = self.parser.add_subparsers(help=gettext('%s_SUBPARSER_HELP' % str(self.mod).upper()))
self.parser.add_argument_group(self.mod, gettext('%s_GROUP_DESC' % str(self.mod).upper()))
def endpoint(self, endpoint, **kwargs):
""" Create an endpoint to define a method on behalf of subparser"""
ref = self
def decorator(f):
"""
Create subparser for controller object
@param f as a function to call
@return decorator method
"""
# TODO Set given function f as a subparser destination
new_sub_parser = ref.subparsers.add_parser(endpoint, help=gettext('%s_%s_HELP' % (ref.mod, endpoint)))
[new_sub_parser.add_argument("--%s" % arg, action='store') for arg in ref.endpoints[ref.mod][endpoint]["params"]]
setattr(ConsoleInterface, 'do_%s' % endpoint, f)
return decorator
And here is how I call it inside the class:
from src.app.controller import Controller
network = Controller("network")
@network.endpoint('create')
def create(*args):
try:
print "I am here"
except Exception as err:
print err
What I am expecting here is create some parsers as command like this:
$~ network create [arguments]
According to the ArgParse docs I do everything right, but I got the exception like:
File "/projectpath/src/app/controller/__init__.py", line 48, in decorator
new_sub_parser = ref.subparsers.add_parser(endpoint, help=gettext('%s_%s_HELP' % (ref.mod, endpoint)))
File "/usr/lib/python2.7/argparse.py", line 1066, in add_parser
parser = self._parser_class(**kwargs)
TypeError: __init__() got an unexpected keyword argument 'prog'
When I look at the ArgParse._SubParsersAction.__init()__
it covers 'prog' inside kwargs.
I had the same problem!
I created my class ArgParser
which extends argparse.ArgumentParser
, and inside it, I had self.add_subparsers()
call, which caused this problem.
class ArgParser(argparse.ArgumentParser):
"""A class to group all the arg parse stuff.
You dont need to pay attention here unless you want to edit CLI args spec"""
def __init__(self):
p_args = dict(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
super().__init__(**p_args)
self.add_argument('-v', '--version', action='version', version=f'%(prog)s {__version__}')
sub_ps = self.add_subparsers(dest='cmd')
sub_ps.required = True
# ... and lot other stuff
so, that causes TypeError: __init__() got an unexpected keyword argument 'prog'
Explicitly set parser_class=argparse.ArgumentParser
as in
sub_ps = self.add_subparsers(dest='cmd', parser_class=argparse.ArgumentParser)
The problem may be with ArgParser()
class. I don't know what that is, though it may be a customized argparse.ArgumentParser
(as subclass).
add_parser
makes sure there is a prog
in the kwargs
, which it then passes to parser = self._parser_class(**kwargs)
. _parser_class
is the class of the main parser unless an alternative is specified in the add_subparsers
line.
So I'm guessing that ArgParser
does not accept a prog
keyword, even though ArgumentParser
does. But I don't think we can help you without knowing more about its source.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With