Last active
December 31, 2017 10:25
-
-
Save TheWaWaR/b88baf7f82ed6bea58959ff7340ff409 to your computer and use it in GitHub Desktop.
An argparse helper
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# coding: utf-8 | |
""" | |
A simple argparse helper. | |
Features: | |
========= | |
* Make nesting commands more elegant and easy to write. | |
* Without lose argparse's ability (means you can refactor current code) | |
""" | |
class Arg(object): | |
""" A class to save arguments passing to a class or function | |
[Use cases]: | |
1. parser.add_argument('-c', '--code', help=u'User code') | |
Equals to: arguments=[Arg('-c', '--code', help=u'User code')] | |
2. subparsers.add_parser('add_role', help=u'Add role to a user') | |
Equals to: ParserConfig(Arg('add_role', help=u'Add role to a user')) | |
""" | |
def __init__(self, *args, **kwargs): | |
self.args = args | |
self.kwargs = kwargs | |
class ParserConfig(object): | |
""" A config to build a parser or subparser """ | |
def __init__(self, | |
parser_args, | |
arguments=None, | |
defaults=None, | |
subparsers=None): | |
arguments = arguments or [] | |
defaults = defaults or {} | |
subparsers = subparsers or [] | |
self.parser_args = parser_args | |
self.arguments = arguments | |
self.defaults = defaults | |
self.subparsers = subparsers | |
self.check_args() | |
def check_args(self): | |
""" Check the type of attributes """ | |
assert isinstance(self.parser_args, Arg) | |
assert isinstance(self.arguments, (list, tuple)) | |
assert isinstance(self.defaults, dict) | |
assert isinstance(self.subparsers, (list, tuple)) | |
for argument in self.arguments: | |
assert isinstance(argument, Arg) | |
for subparser in self.subparsers: | |
assert isinstance(subparser, ParserConfig) | |
def build(self, parser): | |
""" Build the parser or subparser recursively """ | |
for argument in self.arguments: | |
parser.add_argument(*argument.args, **argument.kwargs) | |
parser.set_defaults(**self.defaults) | |
if self.subparsers: | |
sp = parser.add_subparsers() | |
for sub_config in self.subparsers: | |
sub_config.build(sp.add_parser( | |
*sub_config.parser_args.args, | |
**sub_config.parser_args.kwargs | |
)) | |
if __name__ == '__main__': | |
# A simple use case. | |
import argparse | |
parser = argparse.ArgumentParser() | |
parser_config = ParserConfig( | |
Arg(), | |
arguments=[ | |
Arg('-v', '--verbose', action='store_true', | |
help=u'Verbose log'), | |
Arg('--dry', action='store_true', | |
help=u'Do not run real function'), | |
], | |
subparsers=[ | |
ParserConfig( | |
Arg('user', help=u'User management'), | |
# You can put `subparsers` some where above `parser_config`. | |
subparsers=[ | |
ParserConfig( | |
Arg('list', help=u'List all user'), | |
defaults=dict(func=lambda x: x) | |
), | |
ParserConfig( | |
Arg('add', help=u'Add a user'), | |
arguments=[ | |
Arg('-c', '--code', required=True, | |
help=u'User code'), | |
Arg('--name', required=True, | |
help=u'User name'), | |
Arg('--description', default='', | |
help=u'The description'), | |
], | |
defaults=dict(func=lambda x: x) | |
), | |
ParserConfig( | |
Arg('add_role', help=u'Add role to a user'), | |
arguments=[ | |
Arg('-c', '--code', required=True, | |
help=u'Target user code'), | |
Arg('-r', '--role', required=True, | |
help=u'The role name') | |
], | |
defaults=dict(func=lambda x: x) | |
), | |
ParserConfig( | |
Arg('remove_role', help=u'Remove a role from a user'), | |
arguments=[ | |
Arg('-c', '--code', required=True, | |
help=u'Target user code'), | |
Arg('-r', '--role', | |
help=u'The role name'), | |
], | |
defaults=dict(func=lambda x: x) | |
), | |
] | |
), | |
ParserConfig( | |
Arg('test', help=u'Run some test'), | |
arguments=[Arg('-l', '--log', help=u'Output log file')], | |
defaults=dict(func=lambda x: x), | |
), | |
] | |
) | |
parser_config.build(parser) | |
args = parser.parse_args() | |
print(u'Args: {}'.format(args)) | |
# $> python simple_argparse.py user --help | |
# usage: simple_argparse.py user [-h] {list,add,add_role,remove_role} ... | |
# positional arguments: | |
# {list,add,add_role,remove_role} | |
# list List all user | |
# add Add a user | |
# add_role Add role to a user | |
# remove_role Remove a role from a user | |
# optional arguments: | |
# -h, --help show this help message and exit |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment