User reference¶
Clize deduces what kind of parameter to pick for the CLI depending on what kind of parameter is found on the Python function as well as its annotations.
Note
Python 2 compatibility
In this document we will be showing examples that use Python 3 syntax such
as annotations and keyword-only parameters for conciseness. To translate
those into Python 2, you can use sigtools.modifiers.kwoargs
and
sigtools.modifiers.annotate
.
For instance, given this Python 3 function:
def func(ab:int, *, cd:'c'=2):
pass
You would write in Python 2:
from sigtools import modifiers
@modifiers.kwoargs('cd')
@modifiers.annotate(ab=int, cd='c')
def func(ab, cd=2):
pass
You can pass annotations as a sequence:
def func(*, param:('p', int)): pass
def func(*, param:['p', int]): pass
When only one annotation is needed, you can omit the sequence:
def func(*, param:'p'): pass
def func(*, param:('p',)): pass
def func(*, param:['p']): pass
Annotations for parameters that handle a value¶
The positional and options parameters detailed later both handle the following features:
Specifying a value converter¶
A function or callable decorated with parser.value_converter
passed as
annotation will be used during parsing to convert the value from the string
found in sys.argv
into a value suitable for the annotated function.
from clize import run, parser
@parser.value_converter
def wrap_xy(arg):
return 'x' + arg + 'y'
def func(a, b:wrap_xy):
print(repr(a), repr(b))
run(func)
$ python valconv.py abc def
'abc' 'xdefy'
def
was transformed into xdefy
because of the value converter.
Besides callables decorated with parser.value_converter
, the built-in
functions int
, float
and bool
are also recognized as value converters.
Specifying a default value¶
The parameter’s default value is used without conversion. If no value converter is specified, its type is used instead. When a default value is specified, the parameter becomes optional.
>>> def func(par=3):
... print(repr(par))
...
>>> run(func, exit=False, args=['func', '46'])
46
>>> run(func, exit=False, args=['func'])
3
Therefore, be careful not to use values of types for which the constructor does not handle strings, unless you specify a converter:
>>> from datetime import datetime
>>> now = datetime.utcnow()
>>> def fail(par=now):
... print(repr(par))
...
>>> run(fail, exit=False, args=['func', '...'])
Traceback (most recent call last):
...
TypeError: an integer is required (got type str)
>>> from dateutil.parser import parse
>>> from datetime import datetime
>>> now = datetime.utcnow()
>>> def func(par:parse=now):
... print(par)
...
>>> run(func, exit=False, args=['func', '1/1/2016'])
2016-01-01 00:00:00
Ignoring the source parameter’s default value¶
-
Parameter.
REQUIRED
¶ Annotate a parameter with this to force it to be required, even if there is a default value in the source.
>>> from clize import run, Parameter >>> def func(par:Parameter.REQUIRED=3): ... pass ... >>> run(func, exit=False, args=['func']) func: Missing required arguments: par Usage: func par
Positional parameters¶
Normal parameters in Python are turned into positional parameters on the CLI.
Plain arguments on the command line (those that don’t start with a -
) are
processed by those and assigned in the order they appear:
from clize import run
def func(posparam1, posparam2, posparam3):
print('posparam1', posparam1)
print('posparam2', posparam2)
print('posparam3', posparam3)
run(func)
$ python posparams.py one two three
posparam1 one
posparam2 two
posparam3 three
It also shares the features detailed in Annotations for parameters that handle a value.
Parameter that collects remaining positional arguments¶
An *args
-like parameter in Python becomes a repeatable positional parameter
on the CLI:
from clize import run
def func(param, *args):
print('param', param)
print('args', args)
run(func)
$ python argslike.py one two three
param one
args ('two', 'three')
-
Parameter.
REQUIRED
When used on an
*args
parameter, requires at least one value to be provided.
You can use clize.parameters.multi
for more options.
Named parameters¶
Clize treats keyword-only parameters as named parameters, which, instead of
their position, get designated by they name preceeded by --
, or by -
if
the name is only one character long.
There are a couple kinds of named parameters detailed along with examples in the sections below.
They all understand annotations to specify alternate names for them: Simply pass them as strings in the parameter’s annotation:
from clize import run
def func(*, par:('p', 'param')):
print('par', par)
run(func)
$ python named.py --par value
par value
$ python named.py -p value
par value
$ python named.py --param value
par value
All parameter names are converted by removing any underscores (_
) off the
extremities of the string and replacing the remaining ones with dashes (-
).
Python 2 support for named parameters¶
Python 2 has no keyword-only parameters. To fill that gap, you can use the
decorators from sigtools.modifiers
to emulate them.
@DECORATOR
def func(ab, cd, de=None, fg=None, hi=None):
...
@DECORATOR |
Parameters that become keyword-only |
---|---|
@kwoargs('cd', 'fg') |
cd and fg |
@kwoargs(start='fg') |
fg and all following parameters |
@autokwoargs |
All parameters with defaut values |
@autokwoargs(exceptions=['fg']) |
Same, except for fg |
Named parameters that take an argument¶
Keyword-only parameters in Python become named parameters on the CLI: They get designated by their name rather than by their position:
from clize import run
def func(arg, *, o, par):
print('arg', arg)
print('o', o)
print('par', par)
run(func)
$ python opt.py -o abc def --par ghi
arg def
o abc
par ghi
$ python opt.py -oabc --par=def ghi
arg ghi
o abc
par def
The parameter is designated by prefixing its name with two dashes (eg.
--par
) or just one dash if the name is only one character long (eg.
-o
). The value is given either as a second argument (first example) or
glued to the parameter name for the short form, glued using an equals sign
(=
) for the long form.
It shares the features of Annotations for parameters that handle a value and Named parameters.
Named parameters that take an integer argument¶
A variant of Named parameters that take an argument used when the value type from Annotations for parameters that handle a value is int
. The only difference is that when designating the parameter
using the short glued form, you can chain other short named parameters
afterwards:
from clize import run
def func(*, i: int, o):
print('i', i)
print('o', o)
run(func)
$ python intopt.py -i42o abcdef
i 42
o abcdef
Flag parameters¶
Flag parameters are named parameters that unlike options
do not take an argument. Instead, they set their corresponding parameter in
Python to True
if mentionned.
You can create them by having a keyword-only parameter take False
as default
value:
from clize import run
def func(*, flag=False):
print('flag', flag)
run(func)
$ python flag.py
flag False
$ python flag.py --flag
flag True
$ python flag.py --flag=0
flag False
Additionally, you can chain their short form on the command line with other short parameters:
from clize import run
def func(*, flag:'f'=False, other_flag:'g'=False, opt:'o'):
print('flag', flag)
print('other_flag', other_flag)
print('opt', opt)
run(func)
$ python glueflag.py -fgo arg
flag True
other_flag True
opt arg
$ python glueflag.py -fo arg
flag True
other_flag False
opt arg
Mapped parameters¶
-
clize.parameters.
mapped
(values, *, list_name='list', case_sensitive=None)[source]¶ Creates an annotation for parameters that maps input values to Python objects.
Parameters: - values (sequence) – A sequence of
pyobj, names, description
tuples. For each item, the user can specify a name fromnames
and the parameter will receive the correspondingpyobj
value.description
is used when listing the possible values. - list_name (str) – The value the user can use to show a list of possible values and their description.
- case_sensitive (bool) – Force case-sensitiveness for the input values. The default is to guess based on the contents of values.
greeting = parameters.mapped([ ('Hello', ['hello', 'hi'], 'A welcoming message'), ('Goodbye', ['goodbye', 'bye'], 'A parting message'), ]) @modifiers.kwoargs('kind') @modifiers.annotate(kind=('k', greeting)) def main(name='world', kind='Hello'): """ name: Who is the message for? kind: What kind of message should be given to name? """ return '{0} {1}!'.format(kind, name)
$ python -m examples.mapped -k list python -m examples.mapped: Possible values for --kind: hello, hi A welcoming message goodbye, bye A parting message $ python -m examples.mapped -k hello Hello world! $ python -m examples.mapped -k hi Hello world! $ python -m examples.mapped -k bye Goodbye world! $ python -m examples.mapped Hello world!
- values (sequence) – A sequence of
Repeatable parameters¶
-
clize.parameters.
multi
(min=0, max=None)[source]¶ For option parameters, allows the parameter to be repeated on the command-line with an optional minimum or maximum. For
*args
-like parameters, just adds the optional bounds.@modifiers.kwoargs('listen') @modifiers.annotate(listen=('l', parameters.multi(min=1, max=3))) def main(listen): """Listens on the given addresses listen: An address to listen on. """ for address in listen: print('Listening on {0}'.format(address))
$ python -m examples.multi -l bacon Listening on bacon $ python -m examples.multi -l bacon -l ham -l eggs Listening on bacon Listening on ham Listening on eggs $ python -m examples.multi -l bacon -l ham -l eggs -l spam python -m examples.multi: Received too many values for --listen Usage: python -m examples.multi [OPTIONS] $ python -m examples.multi python -m examples.multi: Missing required arguments: --listen Usage: python -m examples.multi [OPTIONS]
Decorated arguments¶
-
clize.parameters.
argument_decorator
(f)[source]¶ Decorates a function to create an annotation for adding parameters to qualify another.
@argument_decorator def capitalize(arg, *, capitalize:('c', 'upper')=False, reverse:'r'=False): """ Options to qualify {param}: capitalize: Make {param} uppercased reverse: Reverse {param} """ if capitalize: arg = arg.upper() if reverse: arg = arg[::-1] return arg def main(*args:capitalize): """ args: stuff """ return ' '.join(args)
$ python -m examples.argdeco --help Usage: python -m examples.argdeco [OPTIONS] [[-c] [-r] args...] Arguments: args... stuff Options to qualify args: -c, --capitalize, --upper Make args uppercased -r, --reverse Reverse args Other actions: -h, --help Show the help $ python -m examples.argdeco abc -c def ghi abc DEF ghi
Annotations that work on any parameter¶
The following objects can be used as annotation on any parameter:
Parameter converters¶
Callables decorated with clize.parser.parameter_converter
are used
instead of the default converter to construct a
CLI parameter for the annotated Python parameter.
The callable can return a Parameter
instance or Parameter.IGNORE
to
instruct clize to drop the parameter.
>>> from clize import run, parser
>>> @parser.parameter_converter
... def print_and_ignore(param, annotations):
... print(repr(param), annotations)
... return parser.Parameter.IGNORE
...
>>> def func(par:(print_and_ignore,int)):
... pass
...
>>> run(func, exit=False, args=['func', '--help'])
<Parameter at 0x7fc6b0c3dae8 'par'> (<class 'int'>,)
Usage: func
Other actions:
-h, --help Show the help
Unless you are creating new kinds of parameters this should not be useful to you directly. Note that custom parameter converters are likely to use different conventions than those described in this reference.
See also
Parameter instances¶
A Parameter
instance seen in an annotation will be used to represent that
parameter on the CLI, without any further processing. Using a parameter
converter is recommended over this.
Skipping parameters¶
-
Parameter.
IGNORE
= clize.Parameter.IGNORE¶ Annotate a parameter with this and it will be dropped from the resulting CLI signature.
Note that it is dangerous to use this on anything except:
- On
*args
and**kwargs
-like parameters, - On keyword parameters with defaults.
For instance, clize’s default converter does not handle
**kwargs
:>>> from clize import run, Parameter >>> def fail(**kwargs): ... pass ... >>> run(fail, exit=False) Traceback (most recent call last): ... ValueError: This converter cannot convert parameter 'kwargs'.
However, if we decorate that parameter with
Parameter.IGNORE
, clize ignores it:>>> def func(**kwargs:Parameter.IGNORE): ... pass ... >>> run(func, exit=False) >>> run(func, exit=False, args=['func', '--help']) Usage: func Other actions: -h, --help Show the help
- On
Hiding parameters from the help¶
-
Parameter.
UNDOCUMENTED
= clize.Parameter.UNDOCUMENTED¶ Parameters annotated with this will be omitted from the documentation (
--help
).>>> from clize import run, Parameter >>> def func(*, o1, o2:Parameter.UNDOCUMENTED): ... pass ... >>> run(func, exit=False, args=['func', '--help']) Usage: func [OPTIONS] Options: --o1=STR Other actions: -h, --help Show the help
Forcing arguments to be treated as positional¶
-
Parameter.
LAST_OPTION
= clize.Parameter.LAST_OPTION¶ Annotate a parameter with this and all following arguments will be processed as positional.
>>> from clize import run, Parameter >>> def func(a, b, c, *, d:Parameter.LAST_OPTION, e=''): ... print("a:", a) ... print("b:", b) ... print("c:", c) ... print("d:", d) ... print("e:", e) ... Usage: [OPTIONS] a b c >>> run(func, exit=False, args=['func', 'one', '-d', 'alpha', '-e', 'beta']) a: one b: -e c: beta d: alpha e:
Here,
-e beta
was received by theb
andc
parameters rather thane
, because it was processed after-d alpha
, which triggered the parameterd
which had the annotation.
Retrieving the executable name¶
-
clize.parameters.
pass_name
(param, annotations)[source]¶ Parameters decorated with this will receive the executable name as argument.
This can be either the path to a Python file, or
python -m some.module
. It is also appended with sub-command names.from clize import run, parameters def main(name:parameters.pass_name, arg): print('name:', name) print('arg:', arg) def alt(arg, *, name:parameters.pass_name): print('arg:', arg) print('name:', name) run(main, alt=alt)
$ python pn.py ham name: pn.py arg: ham $ python -m pn ham name: python -m pn arg: ham $ python pn.py --alt spam arg: spam name: pn.py --alt $ python -m pn --alt spam arg: spam name: python -m pn --alt
Inserting arbitrary values¶
-
clize.parameters.
value_inserter
(value_factory)[source]¶ Create an annotation that hides a parameter from the command-line and always gives it the result of a function.
Parameters: value_factory (function) – Called to determine the value to provide for the parameter. The current parser.CliBoundArguments
instance is passed as argument, ie.value_factory(ba)
.from clize import run, parameters @parameters.value_inserter def insert_ultimate_answer(ba): return 42 def main(arg, ans:insert_ultimate_answer): print('arg:', arg) print('ans:', ans) run(main)
$ python ins.py eggs arg: eggs ans: 42
Customizing the help using the docstring¶
Clize draws the text of the --help
output from the wrapped function’s
docstring as well as of its sigtools.wrappers.wrapper_decorator
-based
decorators.
While it allows some amount of customization, the input must follow certain rules and the output is formatted by Clize.
The docstring is divided in units of paragraphs. Each paragraph is separated by two newlines.
Documenting positional parameters¶
To document a parameter, start a paragraph with the name of the parameter you
want to document followed by a colon (:
), followed by text:
from clize import run
def func(one, and_two):
"""
one: Documentation for the first parameter.
and_two: Documentation for the second parameter.
"""
run(func)
$ python docstring.py --help
Usage: docstring.py one and-two
Arguments:
one Documentation for the first parameter.
and-two Documentation for the second parameter.
Other actions:
-h, --help Show the help
Documentation for positional parameters is always shown in the order they appear in the function signature.
Description and footnotes¶
You can add a description as well as footnotes:
from clize import run
def func(one, and_two):
"""
This is a description of the program.
one: Documentation for the first parameter.
and_two: Documentation for the second parameter.
These are footnotes about the program.
"""
run(func)
$ python docstring.py --help
Usage: docstring.py one and-two
This is a description of the program.
Arguments:
one Documentation for the first parameter.
and-two Documentation for the second parameter.
Other actions:
-h, --help Show the help
These are footnotes about the program.
Adding additional information¶
If you wish, you may add additional information about each parameter in a new paragraph below it:
from clize import run
def func(one, and_two):
"""
This is a description of the program.
one: Documentation for the first parameter.
More information about the first parameter.
and_two: Documentation for the second parameter.
More information about the second parameter.
_:_
These are footnotes about the program.
"""
run(func)
To distinguish and_two
‘s information and the footnotes, we inserted a dummy
parameter description between them (_:_
).
$ python docstring.py --help
Usage: docstring.py one and-two
This is a description of the program.
Arguments:
one Documentation for the first parameter.
More information about the first parameter.
and-two Documentation for the second parameter.
More information about the second parameter.
Other actions:
-h, --help Show the help
These are footnotes about the program.
Ordering named parameters¶
Unlike positional parameters, named parameters will be shown in the order they appear in the docstring:
from clize import run
def func(*, one, and_two):
"""
and_two: Documentation for the second parameter.
one: Documentation for the first parameter.
"""
run(func)
$ python docstring.py --help
Usage: docstring.py [OPTIONS]
Options:
--and-two=STR Documentation for the second parameter.
--one=STR Documentation for the first parameter.
Other actions:
-h, --help Show the help
Creating sections¶
Named parameters can be arranged into sections. You can create a section by
having a paragraph end with a colon (:
) before a parameter definition:
from clize import run
def func(*, one, and_two, three):
"""
Great parameters:
and_two: Documentation for the second parameter.
one: Documentation for the first parameter.
Not-so-great parameters:
three: Documentation for the third parameter.
"""
run(func)
$ python docstring.py --help
Usage: docstring.py [OPTIONS]
Great parameters:
--and-two=STR Documentation for the second parameter.
--one=STR Documentation for the first parameter.
Not-so-great parameters:
--three=STR Documentation for the third parameter.
Other actions:
-h, --help Show the help
Unformatted paragraphs¶
You can insert unformatted text (for instance, code examples) by
finishing a paragraph with a colon (:
) and starting the unformatted text with at
least one space of indentation:
from clize import run
def func():
"""
This text
is automatically formatted.
However, you may present code blocks like this:
Unformatted text
More unformatted
text.
"""
$ python docstring.py --help
Usage: docstring.py
This text is automatically formatted. However, you may present code blocks
like this:
Unformatted text
More unformatted
text.
Other actions:
-h, --help Show the help
run(func)
A paragraph with just a colon (:
) will be omitted from the output, but still
trigger unformatted text.