summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichele Simionato <michele.simionato@gmail.com>2010-12-31 14:56:17 +0100
committerMichele Simionato <michele.simionato@gmail.com>2010-12-31 14:56:17 +0100
commit5c95fd5da840a4be6a03922995982d6750b6951c (patch)
tree8a46256e0da7e6d3b236d52ef1b50b9bfe02302b
parent46a22a5342e17aa4dc9dc251b03aef5e2eb41b95 (diff)
downloadmicheles-5c95fd5da840a4be6a03922995982d6750b6951c.tar.gz
Fixed a bug with the help in subcommands (signaled by Paul Jacobson)
-rw-r--r--plac/doc/example13.help9
-rw-r--r--plac/doc/example13.py1
-rw-r--r--plac/doc/test_plac.py5
-rw-r--r--plac/plac.py2
-rw-r--r--plac/plac_core.py47
-rw-r--r--plac/plac_runner.py4
6 files changed, 43 insertions, 25 deletions
diff --git a/plac/doc/example13.help b/plac/doc/example13.help
index 94401ad..08e6f68 100644
--- a/plac/doc/example13.help
+++ b/plac/doc/example13.help
@@ -1,9 +1,10 @@
-usage: example13.py [-h] {status,commit,checkout,help} ...
+usage: example13.py {status,commit,checkout,help} ...
A Fake Version Control System
-optional arguments:
- -h, --help show this help message and exit
-
subcommands:
{status,commit,checkout,help}
+ checkout
+ commit
+ status
+ help
diff --git a/plac/doc/example13.py b/plac/doc/example13.py
index 715f2e1..412a144 100644
--- a/plac/doc/example13.py
+++ b/plac/doc/example13.py
@@ -3,6 +3,7 @@ import plac
class FVCS(object):
"A Fake Version Control System"
commands = 'checkout', 'commit', 'status', 'help'
+ add_help = False
@plac.annotations(
name=('a recognized command', 'positional', None, str, commands))
diff --git a/plac/doc/test_plac.py b/plac/doc/test_plac.py
index df6c060..dda456b 100644
--- a/plac/doc/test_plac.py
+++ b/plac/doc/test_plac.py
@@ -179,6 +179,11 @@ def test_cmd_abbrevs():
assert ['help', 'foo'] == plac.call(cmds, ['h', 'foo'])
expect(SystemExit, plac.call, cmds, ['foo'])
+def test_sub_help():
+ c = Cmds()
+ c.add_help = True
+ expect(SystemExit, plac.call, c, ['commit', '-h'])
+
def test_yield():
def main():
for i in (1, 2, 3):
diff --git a/plac/plac.py b/plac/plac.py
index af01d87..cc7b41d 100644
--- a/plac/plac.py
+++ b/plac/plac.py
@@ -1,6 +1,6 @@
########################## LICENCE ###############################
##
-## Copyright (c) 2010, Michele Simionato
+## Copyright (c) 2010-2011, Michele Simionato
## All rights reserved.
##
## Redistributions of source code must retain the above copyright
diff --git a/plac/plac_core.py b/plac/plac_core.py
index fbd63b8..ec4a562 100644
--- a/plac/plac_core.py
+++ b/plac/plac_core.py
@@ -15,6 +15,30 @@ except NameError: # Python 2.3
from sets import Set as set
from gettext import gettext as _
+
+def getargspec(callableobj):
+ """Given a callable return an object with attributes .args, .varargs,
+ .varkw, .defaults. It tries to do the "right thing" with functions,
+ methods, classes and generic callables."""
+ if inspect.isfunction(callableobj):
+ argspec = getfullargspec(callableobj)
+ elif inspect.ismethod(callableobj):
+ argspec = getfullargspec(callableobj)
+ del argspec.args[0] # remove first argument
+ elif inspect.isclass(callableobj):
+ if callableobj.__init__ is object.__init__: # to avoid an error
+ argspec = getfullargspec(lambda self: None)
+ else:
+ argspec = getfullargspec(callableobj.__init__)
+ del argspec.args[0] # remove first argument
+ elif hasattr(callableobj, '__call__'):
+ argspec = getfullargspec(callableobj.__call__)
+ del argspec.args[0] # remove first argument
+ else:
+ raise TypeError(_('Could not determine the signature of ') +
+ str(callableobj))
+ return argspec
+
def annotations(**ann):
"""
Returns a decorator annotating a function with the given annotations.
@@ -169,7 +193,7 @@ class ArgumentParser(argparse.ArgumentParser):
def _extract_subparser_cmd(self, arglist):
"Extract the right subparser from the first recognized argument"
- optprefix = self.prefix_chars[0]
+ optprefix = self.prefix_chars[0]
name_parser_map = self.subparsers._name_parser_map
for i, arg in enumerate(arglist):
if not arg.startswith(optprefix):
@@ -187,31 +211,18 @@ class ArgumentParser(argparse.ArgumentParser):
elif title:
self.add_argument_group(title=title) # populate ._action_groups
prefixlen = len(getattr(obj, 'cmdprefix', ''))
+ add_help = getattr(obj, 'add_help', True)
for cmd in commands:
func = getattr(obj, cmd[prefixlen:]) # strip the prefix
self.subparsers.add_parser(
- cmd, add_help=False, **pconf(func)).populate_from(func)
+ cmd, add_help=add_help, help=func.__doc__, **pconf(func)
+ ).populate_from(func)
def _set_func_argspec(self, obj):
"""Extracts the signature from a callable object and adds an .argspec
attribute to the parser. Also adds a .func reference to the object."""
- if inspect.isfunction(obj):
- self.argspec = getfullargspec(obj)
- elif inspect.ismethod(obj):
- self.argspec = getfullargspec(obj)
- del self.argspec.args[0] # remove first argument
- elif inspect.isclass(obj):
- if obj.__init__ is object.__init__: # to avoid an error
- self.argspec = getfullargspec(lambda self: None)
- else:
- self.argspec = getfullargspec(obj.__init__)
- del self.argspec.args[0] # remove first argument
- elif hasattr(obj, '__call__'):
- self.argspec = getfullargspec(obj.__call__)
- del self.argspec.args[0] # remove first argument
- else:
- raise TypeError(_('Could not determine the signature of %r') % obj)
self.func = obj
+ self.argspec = getargspec(obj)
parser_registry[obj] = self
def populate_from(self, func):
diff --git a/plac/plac_runner.py b/plac/plac_runner.py
index 6502efc..2fdfc6d 100644
--- a/plac/plac_runner.py
+++ b/plac/plac_runner.py
@@ -1,6 +1,6 @@
#!python
from __future__ import with_statement
-import os, sys, shlex, inspect
+import os, sys, shlex
import plac
def run(fnames, cmd, verbose):
@@ -62,4 +62,4 @@ def main(verbose, interactive, multiline, serve, batch, test, fname=None,
main.add_help = False
if __name__ == '__main__':
- plac.call(main) \ No newline at end of file
+ plac.call(main)