diff options
author | Anthon van der Neut <anthon@mnt.org> | 2014-12-14 13:23:49 +0100 |
---|---|---|
committer | Anthon van der Neut <anthon@mnt.org> | 2014-12-14 13:23:49 +0100 |
commit | a5eee31aeb8483ebc7ee01bd5ff000acb0d8afd1 (patch) | |
tree | 02de0d498c0491a1ac48d2743be5864077b6bb99 | |
parent | 6323274a0d681ef3473c872b232af1c557f3618f (diff) | |
download | ruamel.std.argparse-a5eee31aeb8483ebc7ee01bd5ff000acb0d8afd1.tar.gz |
--help-all added
-rw-r--r-- | README.rst | 107 | ||||
-rw-r--r-- | __init__.py | 24 | ||||
-rw-r--r-- | setup.py | 2 |
3 files changed, 89 insertions, 44 deletions
@@ -18,10 +18,10 @@ Insert the following to be able to specify `aliases subparser definitions in 2.6 and 2.7:: from __future__ import print_function - + import sys from ruamel.std.argparse import ArgumentParser, SubParsersAction - + parser = ArgumentParser() if sys.version_info < (3,): # add aliases support parser.register('action', 'parsers', SubParsersAction) @@ -49,15 +49,15 @@ CountAction Count up and down:: from __future__ import print_function - + from ruamel.std.argparse import CountAction import argparse - + parser = argparse.ArgumentParser() parser.add_argument('--verbose', '-v', action=CountAction, const=1, nargs=0) parser.add_argument('--quiet', '-q', action=CountAction, dest='verbose', const=-1, nargs=0) - + print(parser.parse_args("--verbose -v -q".split())) .. example code countaction.py @@ -76,13 +76,13 @@ SplitAppend Append after splitting on "``,``". Running:: from __future__ import print_function - + from ruamel.std.argparse import SplitAppendAction import argparse - + parser = argparse.ArgumentParser() parser.add_argument('-d', action=SplitAppendAction) - + print(parser.parse_args("-d ab -d cd -d kl -d mn".split())) print(parser.parse_args("-d ab,cd,kl,mn".split())) print(parser.parse_args("-d ab,cd -d kl,mn".split())) @@ -104,14 +104,14 @@ CheckSingleStoreAction Complain if the same option is called multiple times:: from __future__ import print_function - + from ruamel.std.argparse import CheckSingleStoreAction import argparse - + parser = argparse.ArgumentParser() parser.add_argument('--check', '-c', action=CheckSingleStoreAction, const=1, nargs=0) - + print(parser.parse_args("--check -c".split())) .. example code checksingleaction.py @@ -136,9 +136,9 @@ The ``SmartFormatter`` is a subclass of ``argparse.HelpFormatter`` and has the normal formatter as default. Help text can be marked at the beginning for variations in formatting: -- ``R|..`` format raw, i.e. don't wrap and fill out, observer newline -- ``*|..`` format a password help, never echo password defaults -- ``D|..`` add defaults to **all** entries (that is why having ``*|`` +- ``"R|.."`` format raw, i.e. don't wrap and fill out, observer newline +- ``"*|.."`` format a password help, never echo password defaults +- ``"D|.."`` add defaults to **all** entries (that is why having ``*|`` is important) The version string is formatted using _split_lines and preserves any @@ -147,22 +147,22 @@ line breaks in the version string. :: from __future__ import print_function - + from ruamel.std.argparse import SmartFormatter import argparse - - + + def exit(self, *args, **kw): pass - + argparse.ArgumentParser.exit = exit - + # the 'D|....' in the second pass triggers generating defaults for all entries, # while being smart about which one already have a %(default)s - + for index, log_s in enumerate(['log to file', 'D|log to file']): parser = argparse.ArgumentParser(formatter_class=SmartFormatter) - + parser.add_argument('--log', default='abc.log', help=log_s) parser.add_argument('--username', help='username to login with (default: %(default)s)') @@ -170,7 +170,7 @@ line breaks in the version string. parser.add_argument('--recursive', '-r', action='store_true', help="R|recurse into subdirectories \nto find files") parser.set_defaults(username='anthon', password="test123") - + if index > 0: print('--------------------------------------\n') parser.parse_args(["--help"]) @@ -181,25 +181,25 @@ results in:: usage: smartformatter.py [-h] [--log LOG] [--username USERNAME] [--password PASSWORD] [--recursive] - + optional arguments: -h, --help show this help message and exit --log LOG log to file --username USERNAME username to login with (default: anthon) --password PASSWORD password to use for login - --recursive, -r recurse into subdirectories + --recursive, -r recurse into subdirectories to find files -------------------------------------- - + usage: smartformatter.py [-h] [--log LOG] [--username USERNAME] [--password PASSWORD] [--recursive] - + optional arguments: -h, --help show this help message and exit --log LOG log to file (default: abc.log) --username USERNAME username to login with (default: anthon) --password PASSWORD password to use for login (default: *******) - --recursive, -r recurse into subdirectories + --recursive, -r recurse into subdirectories to find files (default: False) @@ -220,20 +220,20 @@ decorators that can be applied to methods of that subclass. A typical use case is:: from __future__ import print_function - + import sys import os - + from ruamel.std.argparse import ProgramBase, option, sub_parser, version, \ SmartFormatter - - + + class TestCmd(ProgramBase): def __init__(self): super(TestCmd, self).__init__( formatter_class=SmartFormatter ) - + # you can put these on __init__, but subclassing TestCmd # will cause that to break @option('--quiet', '-q', help='suppress verbosity', action='store_true', @@ -242,25 +242,25 @@ A typical use case is:: def _pb_init(self): # special name for which attribs are included in help pass - + def run(self): if self._args.func: return self._args.func() - + def parse_args(self, *args): self._parse_args(*args) - + @sub_parser(help='specific help for readit') @option('--name', default='abc') def readit(self): print('calling readit') - + @sub_parser('writeit', help='help for writeit') @option('--target') def other_name(self): print('calling writeit') - - + + n = TestCmd() n.parse_args(['--help']) n.run() @@ -270,12 +270,12 @@ A typical use case is:: and output:: usage: testcmd.py [-h] [--quiet] [--version] {readit,writeit} ... - + positional arguments: {readit,writeit} readit specific help for readit writeit help for writeit - + optional arguments: -h, --help show this help message and exit --quiet, -q suppress verbosity @@ -303,6 +303,31 @@ them on the special handled method ``_pb_init`` if subclassing might happen. Care should be taken that all attributes on ``TestCmd`` are accessed -during scanning for sub parsers. In particular any property method +during scanning for sub parsers. In particular any property method will be accessedi and its code executed. +Default command +--------------- + +In case you want to have specific sub_parser be invoked as the default, you +can use:: + + self._parse_args(default_sub_parser='show') + +to have the following invocations on the commandline of a program called +``pass`` be the same:: + + pass + pass show + +Help on all subcommands +----------------------- + +If you provide a True value to the optional help_all parameter for +``self._parse_args()``:: + + self._parse_args(help_all=True) + +then the commandline is checked for the option ``--help-all`` and the global +help is printed, follow by the help for each sub parsers, separated by a dashed +line. diff --git a/__init__.py b/__init__.py index 0ff9c30..9a7ce66 100644 --- a/__init__.py +++ b/__init__.py @@ -33,7 +33,7 @@ def _convert_version(tup): # < -version_info = (0, 3, 2) +version_info = (0, 4) __version__ = _convert_version(version_info) del _convert_version @@ -209,7 +209,13 @@ class ProgramBase(object): else: # add long option based on function name arg.insert(0, '--' + fun_name) - parser.add_argument(*arg, **o['kw']) + + try: + parser.add_argument(*arg, **o['kw']) + except ValueError: + print('argparse.ProgramBase arg:', repr(arg)) + print('argparse.ProgramBase kw:', o['kw']) + raise return ssp def dump(method_name_list, level=0): @@ -357,6 +363,20 @@ class ProgramBase(object): name = kw.pop('default_sub_parser', None) if name is not None: self._parser.set_default_subparser(name, args=kw.get('args')) + if kw.pop('help_all', None): + tmp_args = args if args else sys.argv[1:] + if '--help-all' in tmp_args: + try: + self._parser.parse_args(['--help']) + except SystemExit: + pass + for sc in self._methods_with_sub_parsers: + print('-' * 72) + try: + self._parser.parse_args([sc, '--help']) + except SystemExit: + pass + sys.exit(0) self._args = self._parser.parse_args(*args, **kw) return self._args @@ -125,7 +125,7 @@ def main(): setup( name=full_package_name, version=version_str, - description="Enhancements to argparse: extra actions, subparser " \ + description="Enhancements to argparse: extra actions, subparser " "aliases, smart formatter, a decorator based wrapper", install_requires=install_requires, long_description=open('README.rst').read(), |