summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthon van der Neut <anthon@mnt.org>2014-10-15 10:50:11 +0200
committerAnthon van der Neut <anthon@mnt.org>2014-10-15 10:50:11 +0200
commit937fd83a0cf7fc443843a09ac05759c6a3ec6d1c (patch)
tree3fb9aae7114ec5a821ce4952f011cfad9f428d13
parent4b51266bb19f7df8c8708485ea97869327d87a06 (diff)
downloadruamel.std.argparse-937fd83a0cf7fc443843a09ac05759c6a3ec6d1c.tar.gz
Added set_default_subparser code as extra method for ArgumentParser.
Added keyword default_sub_parser to ProgramBase._parse_args()
-rw-r--r--Makefile26
-rw-r--r--__init__.py112
-rw-r--r--tox.ini2
3 files changed, 90 insertions, 50 deletions
diff --git a/Makefile b/Makefile
index 433fbce..a44c161 100644
--- a/Makefile
+++ b/Makefile
@@ -2,34 +2,14 @@
UTILNAME:=argparse
PKGNAME:=ruamel.std.argparse
VERSION:=$$(python setup.py --version)
-DIST:=dist/$(PKGNAME)-$(VERSION).tar.gz
-REGEN:=/usr/local/bin/ruamel_util_new util --std argparse --skip-util --skip-hg
+REGEN:=/usr/local/bin/ruamel_util_new util --std Argparse --skip-util --skip-hg
-sdist:
- python setup.py sdist
-
-wheel:
- python setup.py bdist_wheel
+include ~/.config/ruamel_util_new/Makefile.inc
clean:
- rm -rf build .tox $(PKGNAME).egg-info/
+ rm -rf build .tox $(PKGNAME).egg-info/ README.pdf
find . -name "*.pyc" -exec rm {} +
-tar:
- tar tf $(DIST)
-
-devpi:
- devpi upload $(DIST)
-
-regen_setup:
- rm -f ../argparse/setup.py
- $(REGEN)
- pep8 setup.py
-
-regen_makefile:
- rm -f ../$(UTILNAME)/Makefile
- $(REGEN)
-
BBASE:=ssh://hg@bitbucket.org/ruamel
BB:=$(BBASE)/std.$$(/usr/bin/basename $$PWD)
diff --git a/__init__.py b/__init__.py
index 06e9803..4d551d3 100644
--- a/__init__.py
+++ b/__init__.py
@@ -11,6 +11,7 @@ if PY3:
else:
string_types = basestring,
+
# < from ruamel.util.new import _convert_version
def _convert_version(tup):
"""create a PEP 386 pseudo-format conformant string from tuple tup"""
@@ -42,6 +43,10 @@ from argparse import ArgumentParser
class SubParsersAction(argparse._SubParsersAction):
"""support aliases, based on differences of 3.3 and 2.7
+
+ install with:
+ if sys.version_info < (3,): # add aliases support
+ self._argparser.register('action', 'parsers', SubParsersAction)
"""
class _AliasesChoicesPseudoAction(argparse.Action):
@@ -137,14 +142,24 @@ class ProgramBase(object):
ToDo:
- grouping
- mutual exclusion
+ Done:
- Original order/sorted (by kw)
+ - aliases
"""
_methods_with_sub_parsers = []
def __init__(self, *args, **kw):
+ """
+ the 'aliases' keyword does result in the 'aliases' keyword in
+ @sub_parser (as for Py3 in add_parser()) being available for 2.x
+ """
self._verbose = kw.pop('verbose', 0)
+ aliases = kw.pop('aliases', 0)
self._parser = argparse.ArgumentParser(*args, **kw)
+ if aliases and sys.version_info < (3,):
+ self._parser.register('action', 'parsers', SubParsersAction)
+ self._program_base_initialising = True
cls = self
self._sub_parsers = None
methods_with_sub_parsers = [] # list to process, multilevel
@@ -156,7 +171,7 @@ class ProgramBase(object):
ssp = parser.add_subparsers(
dest="subparser_level_{0}".format(level),)
for method_name in method_name_list:
- #print('method', ' ' * level, method_name)
+ # print('method', ' ' * level, method_name)
method = getattr(self, method_name)
all_methods_with_sub_parsers.append(method)
info = method._sub_parser
@@ -231,16 +246,20 @@ class ProgramBase(object):
except TypeError:
print('args, kw', arg, kw)
if global_option:
- #print('global option', arg, len(all_methods_with_sub_parsers))
+ # print('global option',
+ # arg, len(all_methods_with_sub_parsers))
for m in all_methods_with_sub_parsers:
sp = m._sub_parser['parser']
- sp.add_argument(*arg, **kw)
+ # adding _globa_option to allow easy check e.g. in
+ # AppConfig._set_section_defaults
+ sp.add_argument(*arg, **kw)._global_option = True
+ self._program_base_initialising = False
- #print('-------------------')
- #dump(ProgramBase._methods_with_sub_parsers)
+ # print('-------------------')
+ # dump(ProgramBase._methods_with_sub_parsers)
if False:
+ # for x in ProgramBase._methods_with_sub_parsers:
for x in dir(cls):
- #for x in ProgramBase._methods_with_sub_parsers:
if x.startswith('_'):
continue
method = getattr(self, x)
@@ -258,7 +277,7 @@ class ProgramBase(object):
if level > max_depth:
raise NotImplementedError
for method in all_methods_with_sub_parsers:
- if not method in methods_with_sub_parsers:
+ if method not in methods_with_sub_parsers:
continue
parent = method._sub_parser['kw'].get('_parent', None)
sub_parsers = self._sub_parsers
@@ -266,7 +285,7 @@ class ProgramBase(object):
method._sub_parser['level'] = 0
# parent sub parser
elif 'level' not in parent._sub_parser:
- #print('skipping', parent.__name__, method.__name__)
+ # print('skipping', parent.__name__, method.__name__)
continue
else: # have a parent
# make sure _parent is no longer in kw
@@ -327,19 +346,23 @@ class ProgramBase(object):
except TypeError:
print('args, kw', arg, kw)
if global_option:
- #print('global option', arg, len(all_methods_with_sub_parsers))
+ # print('global option', arg,
+ # len(all_methods_with_sub_parsers))
for m in all_methods_with_sub_parsers:
sp = m._sub_parser['parser']
sp.add_argument(*arg, **kw)
def _parse_args(self, *args, **kw):
+ name = kw.pop('default_sub_parser', None)
+ if name is not None:
+ self._parser.set_default_subparser(name, args=kw.get('args'))
self._args = self._parser.parse_args(*args, **kw)
return self._args
- #def _parse_known_args(self, *args, **kw):
- # self._args, self._unknown_args = \
- # self._parser.parse_known_args(*args, **kw)
- # return self._args
+ # def _parse_known_args(self, *args, **kw):
+ # self._args, self._unknown_args = \
+ # self._parser.parse_known_args(*args, **kw)
+ # return self._args
@staticmethod
def _pb_option(*args, **kw):
@@ -401,19 +424,24 @@ class ProgramBase(object):
def option(*args, **keywords):
"""\
-args:
- name or flags - Either a name or a list of option strings, e.g. foo or -f, --foo.
-keywords:
- action - The basic type of action to be taken when this argument is encountered at the command line.
- nargs - The number of command-line arguments that should be consumed.
- const - A constant value required by some action and nargs selections.
- default - The value produced if the argument is absent from the command line.
- type - The type to which the command-line argument should be converted.
- choices - A container of the allowable values for the argument.
- required - Whether or not the command-line option may be omitted (optionals only).
- help - A brief description of what the argument does.
- metavar - A name for the argument in usage messages.
- dest - The name of the attribute to be added to the object returned by parse_args().
+ args:
+ name or flags - Either a name or a list of option strings, e.g. foo or
+ -f, --foo.
+ keywords:
+ action - The basic type of action to be taken when this argument is
+ encountered at the command line.
+ nargs - The number of command-line arguments that should be consumed.
+ const - A constant value required by some action and nargs selections.
+ default - The value produced if the argument is absent from the command
+ line.
+ type - The type to which the command-line argument should be converted.
+ choices - A container of the allowable values for the argument.
+ required - Whether or not the command-line option may be omitted
+ (optionals only).
+ help - A brief description of what the argument does.
+ metavar - A name for the argument in usage messages.
+ dest - The name of the attribute to be added to the object returned by
+ parse_args().
"""
return ProgramBase._pb_option(*args, **keywords)
@@ -425,3 +453,35 @@ def sub_parser(*args, **kw):
def version(version_string):
return ProgramBase._pb_option(
'--version', action='version', version=version_string)
+
+
+# extra ArgumentParser functionality
+
+def set_default_subparser(self, name, args=None):
+ """default subparser selection. Call after setup, just before parse_args()
+ name: is the name of the subparser to call by default
+ args: if set is the argument list handed to parse_args()
+
+ , tested with 2.7, 3.2, 3.3, 3.4
+ it works with 2.6 assuming argparse is installed
+ """
+ subparser_found = False
+ for arg in sys.argv[1:]:
+ if arg in ['-h', '--help']: # global help if no subparser
+ break
+ else:
+ for x in self._subparsers._actions:
+ if not isinstance(x, argparse._SubParsersAction):
+ continue
+ for sp_name in x._name_parser_map.keys():
+ if sp_name in sys.argv[1:]:
+ subparser_found = True
+ if not subparser_found:
+ # insert default in first position, this implies no
+ # global options without a sub_parsers specified
+ if args is None:
+ sys.argv.insert(1, name)
+ else:
+ args.insert(0, name)
+
+argparse.ArgumentParser.set_default_subparser = set_default_subparser
diff --git a/tox.ini b/tox.ini
index 3e3f27e..4082297 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
[tox]
-envlist = py27,py34
+envlist = py26,py27,py33,py34
[testenv]
commands = py.test test