--- a/docs/overview.rst Thu Jul 23 16:52:29 2009 +0300
+++ b/docs/overview.rst Fri Jul 24 13:16:11 2009 +0300
@@ -55,8 +55,27 @@
function. This is done to comply with standarts of writing both console
interfaces and Python application.
-To make your application work, just call ``main()`` (it will parse
-``sys.argv``).
+After that you can simply call this function as an entry point to your program::
+
+ if __name__ == '__main__':
+ main()
+
+This will run command line parsing facility, using arguments from
+``sys.argv``. ``%name`` will be replaced with ``sys.argv[0]`` (or prepended to
+usage string if there is no ``%name``), and rest of arguments will be passed to
+command line parser. In case if rest is empty, help will be displayed.
+
+Of course, you can use your function programmatically, supplying list of
+arguments to function::
+
+ main('-l 0.0.0.0 /my/dir'.split())
+
+Or, if you need this, you can call this function as usual::
+
+ main('/my/dir', listen='0.0.0.0')
+
+In this case no type conversion (which is done upon arguments parsing) will be
+performed.
Subcommands
-----------
--- a/finaloption.py Thu Jul 23 16:52:29 2009 +0300
+++ b/finaloption.py Fri Jul 24 13:16:11 2009 +0300
@@ -36,7 +36,11 @@
'''
def wrapper(func):
# copy option list
- options_ = list(options or guess_options(func))
+ try:
+ options_ = list(options or guess_options(func))
+ except TypeError:
+ # no options supplied and no options present in func
+ options_ = []
name_ = name or func.__name__
CMDTABLE[(shortlist and '^' or '') + name_] = (
@@ -48,24 +52,33 @@
name_ = name_[2:]
return help_cmd(func, replace_name(usage, name_), options_)
- def inner(args=None):
+ @wraps(func)
+ def inner(*arguments, **kwarguments):
+ # look if we need to add 'help' option
try:
(True for option in reversed(options_)
if option[1] == 'help').next()
except StopIteration:
options_.append(('h', 'help', False, 'show help'))
- args = args or sys.argv[1:]
- if not args:
- return help_func()
+ args = kwarguments.pop('args', None)
+ if arguments or kwarguments:
+ args, opts = arguments, kwarguments
+ else:
+ args = args or sys.argv[1:]
+ if not args:
+ return help_func()
+ try:
+ opts, args = catcher(lambda: parse(args, options_),
+ help_func)
+ except Abort:
+ return -1
try:
- opts, args = catcher(lambda: parse(args, options_), help_func)
if opts.pop('help', False):
return help_func()
- return catcher(
- lambda: call_cmd(name_, func, *args, **opts),
- help_func)
+ return catcher(lambda: call_cmd(name_, func, *args, **opts),
+ help_func)
except Abort:
return -1
@@ -419,6 +432,19 @@
return usage.replace('%name', name, 1)
return name + ' ' + usage
+try:
+ from functools import wraps
+except ImportError:
+ def wraps(wrapped, assigned=('__module__', '__name__', '__doc__'),
+ updated=('__dict__',)):
+ def inner(wrapper):
+ for attr in assigned:
+ setattr(wrapper, attr, getattr(wrapped, attr))
+ for attr in updated:
+ getattr(wrapper, attr).update(getattr(wrapped, attr, {}))
+ return wrapper
+ return inner
+
# --------
# Exceptions
# --------
--- a/test_opts.py Thu Jul 23 16:52:29 2009 +0300
+++ b/test_opts.py Fri Jul 24 13:16:11 2009 +0300
@@ -25,7 +25,7 @@
pid_file=('', '', 'name of file to write process ID to')):
'''Command with option declaration as keyword arguments
- Otherwise it's the same as previons command
+ Otherwise it's the same as previous command
'''
print locals()