command-line parser
Ben Wolfson
rumjuggler at cryptarchy.org
Sun Jun 18 17:36:29 EDT 2000
"""
arglist.py
A utility for retrieving arguments passed via the command line.
"""
class Error(Exception):
pass
class Arguments:
"""
Instantiate with tuples of acceptable options. Tuples should have the form
(short_form, long_form, accepts_value, default_value)
Either short_form or long_form can be None or a false value, if there is no
short
or long equivalent of the option, but not both (obviously). If
accepts_value is true
and default_value is None, the instance will assume that a value is
necessary, and
raise Error if the option but no value is present. Short_form and
long_form should
_not_ be passed with leading dashes.
__getattr__ is used to find out if an option is passed. If the instance is
instantiated as
>>> arg = arglist.Arguments(
('h', 'help', None, None),
('p', 'port', 1, 5555),
('l', 'lalala', 1, None),
('a', 'anotheropt', 1, 21)
)
and the command line options are --port -l --anotheropt=haha
>>> arg.process(['--port', '-l:2', '--anotheropt=haha'])
then the following should result:
>>> arg.h
>>> print arg.h
None
>>> arg.help
>>> print arg.help
None
>>> arg.port
5555
>>> arg.p
5555
>>> arg.l
'2'
>>> arg.lalala
'2'
>>> arg.a
'haha'
>>> arg.anotheropt
'haha'
It is possible to verify that arguments are a certain type using
__setattr__.
To verify that the argument to -a or --anotheropt is an int, you would do:
arg.a = int
This will raise a SystemExit exception if arg.a cannot be converted to an
int using the function int().
"""
class Option:
def __init__(self, opt):
if '=' in opt:
opt, self.arg = opt.split('=',2)
elif ':' in opt:
opt, self.arg = opt.split(':',2)
else:
self.arg = None
if opt[:2] == '--':
self.option = opt[2:]
else:
self.option = opt[1:]
def __init__(self, *args):
self.__dict__['dict'] = {}
for short, long, hasvalue, default in args:
if short and long:
self.dict[short] = self.dict[long] = [hasvalue, default]
elif short:
self.dict[short] = [hasvalue, default]
elif long:
self.dict[long] = [hasvalue, default]
else:
raise Error, "Option must have either a short or a long
key"
self.__dict__['nonopts'] = []
def process(self, options):
dict = self.dict
for i in range(len(options)):
if options[i][0] <> '-':
self.nonopts.append(options[i])
del options[i]
for opt in map(Arguments.Option, options):
option = opt.option
if not self.dict.has_key(option):
raise Error, "Unrecognized option %s" % option
hasvalue, default = dict[option]
if not hasvalue:
dict[option][1] = default or 1
else:
if opt.arg is None:
if default is None:
raise Error, "Value must be provided for option %s"
% option
else:
dict[option][1] = default
else:
dict[option][1] = opt.arg
def get_nonopts(self):
return self.nonopts
def __getattr__(self, key):
dict = self.dict
if not dict.has_key(key):
raise Error, 'No option %s' % key
return dict[key][1]
def __setattr__(self, key, _type):
dict = self.dict
if not dict.has_key(key):
raise Error, 'No option %s' % key
value = dict[key][1]
try:
_type(value)
except ValueError:
raise SystemExit
except TypeError:
raise SystemExit
More information about the Python-list
mailing list