Parsing keyword-style program arguments (pwkit.kwargv
)¶
The pwkit.kwargv
module provides a framework for parsing
keyword-style arguments to command-line programs. It’s designed so that you
can easily make a routine with complex, structured configuration parameters
that can also be driven from the command line.
Keywords are defined by declaring a subclass of the
ParseKeywords
class with fields corresponding to the
support keywords:
from pwkit.kwargv import ParseKeywords, Custom
class MyConfig(ParseKeywords):
foo = 1
bar = str
multi = [int]
extra = Custom(float, required=True)
@Custom(str)
def declination(value):
from pwkit.astutil import parsedeglat
return parsedeglat(value)
Instantiating the subclass fills in all defaults. Calling the
ParseKeywords.parse()
method parses a list of strings (defaulting to
sys.argv[1:]
) and updates the instance’s properties. This framework is
designed so that you can provide complex configuration to an algorithm either
programmatically, or on the command line. A typical use would be:
from pwkit.kwargv import ParseKeywords, Custom
class MyConfig(ParseKeywords):
niter = 1
input = str
scales = [int]
# ...
def my_complex_algorithm(cfg):
from pwkit.io import Path
data = Path(cfg.input).read_fits()
for i in range(cfg.niter):
# ....
def call_algorithm_in_code():
cfg = MyConfig()
cfg.input = 'testfile.fits'
# ...
my_complex_algorithm(cfg)
if __name__ == '__main__':
cfg = MyConfig().parse()
my_complex_algorithm(cfg)
You could then execute the module as a program and specify arguments in the
form ./program niter=5 input=otherfile.fits
.
Keyword Specification Format¶
Arguments are specified in the following ways:
foo = 1
defines a keyword with a default value, type inferred asint
. Likewise forstr
,bool
,float
.bar = str
defines an string keyword with default value of None. Likewise forint
,bool
,float
.multi = [int]
parses as a list of integers of any length, defaulting to the empty list[]
(I call these “flexible” lists.). List items are separated by commas on the command line.other = [3.0, int]
parses as a 2-element list, defaulting to[3.0, None]
. If one value is given, the first array item is parsed, and the second is left as its default. (I call these “fixed” lists.)extra = Custom(float, required=True)
parses likefloat
and then customizes keyword properties. Supported properties are the attributes of theKeywordInfo
class.Use
Custom
as a decorator (@Custom
) on a functionfoo
defines a keywordfoo
that’s parsed according to theCustom
specification, then has its value fixed up by calling thefoo()
function after the basic parsing. That is, the final value isfoo (intermediate_value)
. A common pattern is to use a fixup function for a fixed list where the first few values are mandatory (seeKeywordInfo.minvals
below) but later values can be guessed or defaulted.
See the KeywordInfo
documentation for specification of additional
keyword properties that may be specified. The Custom
name is simply an
alias for KeywordInfo
.
- pwkit.kwargv.Custom¶
alias of
KeywordOptions
- class pwkit.kwargv.KeywordInfo[source]¶
Properties that a keyword argument may have.
- default = None¶
The default value for the keyword if it’s left unspecified.
- fixupfunc = None¶
If not
None
, the final value of the keyword is set to the return value offixupfunc(intermediate_value)
.
- maxvals = None¶
The maximum number of values allowed. This only applies for flexible lists; fixed lists have predetermined sizes.
- minvals = 0¶
The minimum number of values allowed in a flexible list, if the keyword is specified at all. If you want
minvals = 1
, userequired = True
.
- parser = None¶
A callable used to convert the argument text to a Python value. This attribute is assigned automatically upon setup.
- printexc = False¶
Print the exception as normal if there’s an exception when parsing the keyword value. Otherwise there’s just a message along the lines of “cannot parse value <val> for keyword <kw>”.
- repeatable = False¶
If true, the keyword value(s) will always be contained in a list. If they keyword is specified multiple times (i.e.
./program kw=1 kw=2
), the list will have multiple items (cfg.kw = [1, 2]
). If the keyword is list-valued, using this will result in a list of lists.
- required = False¶
Whether an error should be raised if the keyword is not seen while parsing.
- scale = None¶
If not
None
, multiply numeric values by this number after parsing.
- sep = ','¶
The textual separator between items for list-valued keywords.
- uiname = None¶
The name of the keyword as parsed from the command-line. For instance,
some_value = Custom(int, uiname="some-value")
will result in a keyword that the user sets by calling./program some-value=3
. This provides a mechanism to support keyword names that are not legal Python identifiers.
- exception pwkit.kwargv.KwargvError(fmt, *args)[source]¶
Raised when invalid arguments have been provided.
- exception pwkit.kwargv.ParseError(fmt, *args)[source]¶
Raised when the structure of the arguments appears legitimate, but a particular value cannot be parsed into its expected type.
- class pwkit.kwargv.ParseKeywords[source]¶
The template class for defining your keyword arguments. A subclass of
pwkit.Holder
. Declare attributes in a subclass following the scheme described above, then call theParseKeywords.parse()
method.- parse(args=None)[source]¶
Parse textual keywords as described by this class’s attributes, and update this instance’s attributes with the parsed values. args is a list of strings; if
None
, it defaults tosys.argv[1:]
. Returns self for convenience. RaisesKwargvError
if invalid keywords are encountered.See also
ParseKeywords.parse_or_die()
.
- parse_or_die(args=None)[source]¶
Like
ParseKeywords.parse()
, but callspkwit.cli.die()
if aKwargvError
is raised, printing the exception text. Returns self for convenience.
- pwkit.kwargv.basic(args=None)[source]¶
Parse the string list args as a set of keyword arguments in a very simple-minded way, splitting on equals signs. Returns a
pwkit.Holder
instance with attributes set to strings. The form+foo
is mapped to settingfoo = True
on thepwkit.Holder
instance. If args isNone
,sys.argv[1:]
is used. RaisesKwargvError
on invalid arguments (i.e., ones without an equals sign or a leading plus sign).