piranha/opster — pull request #31 by oscarbenjamin (2012-05-18 23:34:12+00:00)
Title: Add support for keyword-only arguments in py3k

Hi again.

This patch adds support and tests for keyword-only arguments in functions wrapped by ```@command```. I had to modify the makefile and create a new .t file so that there could be tests that would only run for python3.

Python 3 supports keyword only arguments. If these had been available when opster was written it would definitely have made sense to use them. This way, you can write:

@command()
def main(*args, opt1=('o', False, 'first option')):
pass

This means that opster can easily distinguish positional arguments and keyword arguments (since there is no overlap). It means that opster does not need to check the type (```isinstance(default, tuple)```) in order to identify an option argument. It also means that the ```command``` decorator does not even need to wrap the ```main``` function and could just return it with the default values modified (no need for ```call_cmd_regular```). Finally, it makes the code clearer even if ```*args``` is not used, e.g.:

@command()
def main(arg1, arg2=None, *,
opt1=('o', False, 'first option')):
pass

Keyword-only arguments are only supported in python3. Also ```inspect.getargspec``` is deprecated in python3 and raises ```ValueError``` if its input has keyword-only arguments. This makes it a bit fiddly to support both cases simultaneously. The current patch will assume if the function has any keyword only arguments that all of them are for options (and that all other arguments are positional).

If python2.x stops being supported for new opster releases, I think it would be good to drop support for using argument inspection without keyword-only arguments so that in future all opster scripts written on python3 use keyword-only arguments.

Cheers,
Oscar.