Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 2 commits
  • 5 files changed
  • 0 commit comments
  • 2 contributors
Commits on May 18, 2012
Oscar Benjamin oscarbenjamin Add support for keyword-only arguments in py3k 531af36
Commits on May 21, 2012
Alexander Solovyov Merge pull request #31 from oscarbenjamin/kwonly
Add support for keyword-only arguments in py3k
fc87dba
7 Makefile
View
@@ -23,17 +23,18 @@ arch:
test:
python opster.py
- $(CRAM) tests/*.t
+ $(CRAM) tests/opster.t
test2to3:
"$(PYTHON3)" setup.py build
2to3 --doctests_only --write "$(BUILD_DIR)"/opster.py
"$(PYTHON3)" "$(BUILD_DIR)"/opster.py
- PYTHON="$(PYTHON3)" OPSTER_DIR="$(BUILD_DIR)" $(CRAM) tests/*.t
+ PYTHON="$(PYTHON3)" OPSTER_DIR="$(BUILD_DIR)" $(CRAM) tests/opster.t
+ PYTHON="$(PYTHON3)" OPSTER_DIR="$(BUILD_DIR)" $(CRAM) tests/py3k.t
coverage:
coverage run -a opster.py
- COVERAGE=1 $(CRAM) tests/*.t
+ COVERAGE=1 $(CRAM) tests/opster.t
upload:
python setup.py sdist upload
32 opster.py
View
@@ -689,20 +689,43 @@ def func(longname=(shortname, default, help)):
See docstring of ``command()`` for description of those variables.
'''
- args, _, _, defaults = inspect.getargspec(func)
+ try:
+ args, _, _, defaults = inspect.getargspec(func)
+ except ValueError: # has keyword-only arguments
+ for o in guess_options_py3k(func):
+ yield o
+ return
for name, option in zip(args[-len(defaults):], defaults):
if not isinstance(option, tuple):
continue
yield (option[0], name_from_python(name)) + option[1:]
+def guess_options_py3k(func):
+ '''Get options definitions from function with keyword-only arguments
+
+ They should be declared in a following way:
+
+ def func(*, longname=(shortname, default, help)):
+ pass
+
+ See docstring of ``command()`` for description of those variables.
+ '''
+ spec = inspect.getfullargspec(func)
+ for name, option in spec.kwonlydefaults.items():
+ yield (option[0], name_from_python(name)) + option[1:]
+
+
def guess_usage(func, options):
'''Get usage definition for a function
'''
usage = ['%name']
if options:
usage.append('[OPTIONS]')
- arginfo = inspect.getargspec(func)
+ try:
+ arginfo = inspect.getargspec(func)
+ except ValueError: # keyword-only args
+ arginfo = inspect.getfullargspec(func)
optnames = [o.name for o in options]
nonoptional = len(arginfo.args) - len(arginfo.defaults or ())
@@ -768,7 +791,10 @@ def call_cmd(name, func, opts, middleware=None):
'''Wrapper for command call, catching situation with insufficient arguments.
'''
# depth is necessary when there is a middleware in setup
- arginfo = inspect.getargspec(func)
+ try:
+ arginfo = inspect.getargspec(func)
+ except ValueError:
+ arginfo = inspect.getfullargspec(func)
if middleware:
tocall = middleware(func)
depth = 2
9 tests/kwonly.py
View
@@ -0,0 +1,9 @@
+from opster import command
+
+@command()
+def main(arg1, arg2=None, *,
+ opt1=('', 'opt1', 'help for --opt1')):
+ print(arg1, arg2)
+ print(opt1)
+
+main.command()
11 tests/kwonlyvarargs.py
View
@@ -0,0 +1,11 @@
+from opster import command
+
+@command()
+def main(arg1, arg2, arg3=None, arg4='arg4', *args,
+ opt1=('', 'opt1', 'help for --opt1'),
+ opt2=('', 'opt2', 'help for --opt2')):
+ print(arg1, arg2, arg3, arg4)
+ print(args)
+ print(opt1, opt2)
+
+main.command()
143 tests/py3k.t
View
@@ -0,0 +1,143 @@
+.. -*- mode: rst -*-
+
+==================
+ Opster Py3K tests
+==================
+
+This is the opster test suite for tests that are only to be run on python 3.x
+
+.. highlight:: console
+
+Actors cast
+-----------
+
+Choose python version::
+
+ $ if [ -z "$PYTHON" ]; then
+ > PYTHON="python"
+ > fi
+
+Add opster to the PYTHONPATH::
+
+ $ if [ -z "$OPSTER_DIR" ]; then
+ > OPSTER_DIR="$TESTDIR/.."
+ > fi
+ > export PYTHONPATH="$OPSTER_DIR"
+
+Define function to make it simpler::
+
+ $ run() {
+ > name=$1
+ > shift
+ > export COVERAGE_FILE=$TESTDIR/coverage.db
+ > if [ -z "$COVERAGE" ]; then
+ > "$PYTHON" "$TESTDIR/$name" "$@"
+ > else
+ > coverage run -a --rcfile="$TESTDIR/../.coveragerc" "$TESTDIR/$name" "$@"
+ > fi
+ > }
+
+Keyword-only args
+-----------------
+
+Check that opster understand keyword-only args when used without varargs.
+
+ $ run kwonly.py
+ kwonly.py: invalid arguments
+
+ kwonly.py [OPTIONS] ARG1 [ARG2]
+
+ (no help text available)
+
+ options:
+
+ --opt1 help for --opt1 (default: opt1)
+ -h --help display help
+
+ $ run kwonly.py A
+ A None
+ opt1
+
+ $ run kwonly.py A B
+ A B
+ opt1
+
+ $ run kwonly.py A B C
+ kwonly.py: invalid arguments
+
+ kwonly.py [OPTIONS] ARG1 [ARG2]
+
+ (no help text available)
+
+ options:
+
+ --opt1 help for --opt1 (default: opt1)
+ -h --help display help
+
+ $ run kwonly.py A --opt1=newval
+ A None
+ newval
+
+ $ run kwonly.py A B --opt1=newval
+ A B
+ newval
+
+ $ run kwonly.py A B C --opt1=newval
+ kwonly.py: invalid arguments
+
+ kwonly.py [OPTIONS] ARG1 [ARG2]
+
+ (no help text available)
+
+ options:
+
+ --opt1 help for --opt1 (default: opt1)
+ -h --help display help
+
+Keyword-only args and varargs
+-----------------------------
+
+Check that opster understand keyword-only args when used with varargs.
+
+ $ run kwonlyvarargs.py
+ kwonlyvarargs.py: invalid arguments
+
+ kwonlyvarargs.py [OPTIONS] ARG1 ARG2 [ARG3] [ARG4] [ARGS ...]
+
+ (no help text available)
+
+ options:
+
+ --opt1 help for --opt1 (default: opt1)
+ --opt2 help for --opt2 (default: opt2)
+ -h --help display help
+
+ $ run kwonlyvarargs.py A B
+ A B None arg4
+ ()
+ opt1 opt2
+
+ $ run kwonlyvarargs.py A B C D
+ A B C D
+ ()
+ opt1 opt2
+
+ $ run kwonlyvarargs.py A B C D E F
+ A B C D
+ ('E', 'F')
+ opt1 opt2
+
+ $ run kwonlyvarargs.py A B --opt1=newval --opt2=newval2
+ A B None arg4
+ ()
+ newval newval2
+
+ $ run kwonlyvarargs.py A B C D --opt1=newval1 --opt2=newval2
+ A B C D
+ ()
+ newval1 newval2
+
+ $ run kwonlyvarargs.py A B C D E F --opt1=newval1 --opt2=newval2
+ A B C D
+ ('E', 'F')
+ newval1 newval2

No commit comments for this range

Something went wrong with that request. Please try again.