when calling command from python set not supplied options to proper defaults
Earlier you would get full option spec (short, default, help) for every option,
not supplied as argument (or keyword argument) in function call.
--- a/docs/changelog.rst Sun Sep 06 15:08:49 2009 +0300
+++ b/docs/changelog.rst Sun Sep 06 16:32:32 2009 +0300
@@ -3,9 +3,11 @@
0.9.9
~~~~~
- - globaloptions were simply dropped after parsing, fold them in regular options
- - replace _ with - in command names, same as in options names
- - respect empty strings as usage
+ - Now it's possible to call commands as regular function, where every
+ non-supplied option will receive proper default (defined in option spec)
+ - Globaloptions were simply dropped after parsing, fold them in regular options
+ - Replace _ with - in command names, same as in options names
+ - Respect empty strings as usage
0.9.8
~~~~~
--- a/opster.py Sun Sep 06 15:08:49 2009 +0300
+++ b/opster.py Sun Sep 06 16:32:32 2009 +0300
@@ -56,7 +56,7 @@
return help_cmd(func, replace_name(usage_, sysname()), options_)
@wraps(func)
- def inner(*arguments, **kwarguments):
+ def inner(*args, **opts):
# look if we need to add 'help' option
try:
(True for option in reversed(options_)
@@ -64,16 +64,21 @@
except StopIteration:
options_.append(('h', 'help', False, 'show help'))
- args = kwarguments.pop('args', None)
- if arguments or kwarguments:
- args, opts = arguments, kwarguments
- else:
- args = args or sys.argv[1:]
- try:
- opts, args = catcher(lambda: parse(args, options_),
- help_func)
- except Abort:
- return -1
+ argv = opts.pop('args', None)
+ if opts.pop('help', False):
+ return help_func()
+
+ if args or opts:
+ # no catcher here because this is call from Python
+ return call_cmd_regular(func)(*args, **opts)
+
+ if argv is None:
+ argv = sys.argv[1:]
+
+ try:
+ opts, args = catcher(lambda: parse(argv, options_), help_func)
+ except Abort:
+ return -1
try:
if opts.pop('help', False):
@@ -416,6 +421,8 @@
return usage
def catcher(target, help_func):
+ '''Catches all exceptions and prints human-readable information on them
+ '''
try:
return target()
except UnknownCommand, e:
@@ -451,6 +458,18 @@
raise
return inner
+def call_cmd_regular(func):
+ def inner(*args, **kwargs):
+ funcargs, varargs, varkw, defaults = inspect.getargspec(func)
+
+ funckwargs = funcargs[len(args):]
+ funckwargs = dict(zip(funckwargs, (default for _, default, _
+ in defaults[-len(funckwargs):])))
+ funckwargs.update(kwargs)
+
+ return func(*args, **funckwargs)
+ return inner
+
def replace_name(usage, name):
if '%name' in usage:
return usage.replace('%name', name, 1)
--- a/test_cmd.py Sun Sep 06 15:08:49 2009 +0300
+++ b/test_cmd.py Sun Sep 06 16:32:32 2009 +0300
@@ -21,4 +21,5 @@
print opts
-opster.dispatch()
+if __name__ == '__main__':
+ opster.dispatch()