30This module makes it easy to find files in the locations that are defined for
31them by the FHS. Some locations are not defined there. This module chooses a
34It also defines a configuration file format which
is used automatically when
35initializing this module.
38'''@package fhs Module
for using paths
as described
in the FHS.
39This module makes it easy to find files
in the locations that are defined
for
40them by the FHS. Some locations are
not defined there. This module chooses a
43It also defines a configuration file format which
is used automatically when
44initializing this module.
48# Paths and how they are handled by this module: {{{
108pname = os.getenv(
'PACKAGE_NAME', os.path.basename(sys.argv[0]))
110HOME = os.path.expanduser(
'~')
143_base = os.path.abspath(os.path.dirname(sys.argv[0]))
148XDG_CONFIG_HOME = os.getenv(
'XDG_CONFIG_HOME', os.path.join(HOME,
'.config'))
150XDG_CONFIG_DIRS = tuple([XDG_CONFIG_HOME] + os.getenv(
'XDG_CONFIG_DIRS',
'/etc/xdg').split(
':'))
160def write_config(name = None, text = True, dir = False, opened = True, packagename = None):
164 filename = packagename
or pname
166 filename = (packagename
or pname) + os.extsep +
'cfg'
168 filename = name
if is_system
else os.path.join(packagename
or pname, name)
170 if packagename
and packagename != pname:
171 d = os.path.join(
'/etc/xdg', pname, packagename)
173 d = os.path.join(
'/etc/xdg', pname)
176 target = os.path.join(d, filename)
178 if opened
and not os.path.exists(target):
182 d = os.path.dirname(target)
183 if opened
and not os.path.exists(d):
185 return open(target,
'w+' if text
else 'w+b')
if opened
else target
196def read_config(name = None, text = True, dir = False, multiple = False, opened = True, packagename = None):
200 filename = packagename
or pname
202 filename = (packagename
or pname) + os.extsep +
'cfg'
208 t = os.path.join(XDG_CONFIG_HOME, filename
if name
is None else os.path.join(packagename
or pname, name))
209 if os.path.realpath(t)
not in seen
and os.path.exists(t)
and (dir
if os.path.isdir(t)
else not dir):
210 r = t
if dir
or not opened
else open(t,
'r' if text
else 'rb')
213 seen.add(os.path.realpath(t))
215 dirs = [
'/etc/xdg',
'/usr/local/etc/xdg']
217 for d
in XDG_CONFIG_DIRS:
219 if packagename
and packagename != pname:
220 dirs = [os.path.join(x, pname, packagename)
for x
in dirs] + [os.path.join(x, packagename)
for x
in dirs]
222 dirs = [os.path.join(x, pname)
for x
in dirs]
224 dirs.insert(0, packagename
or pname)
225 dirs.insert(0, os.path.curdir)
226 dirs.insert(0, _base)
228 t = os.path.join(d, filename)
229 if os.path.realpath(t)
not in seen
and os.path.exists(t)
and (dir
if os.path.isdir(t)
else not dir):
230 r = t
if dir
or not opened
else open(t,
'r' if text
else 'rb')
233 seen.add(os.path.realpath(t))
250 shutil.rmtree(
read_config(name,
False,
True,
False,
False, packagename), ignore_errors =
False)
252 os.unlink(
read_config(name,
False,
False,
False,
False, packagename))
256def _protect(data, extra = ''):
261 if o < 32
or o >= 127
or x
in extra:
273 ret += chr(int(data[1:l], 16))
276 if 32 <= ord(data[0]) < 127:
292 if len(value) < 2
or not value.startswith(
"'")
or not value.endswith(
"'"):
293 raise ValueError(
'str value without quotes')
294 return value[1:-1].replace(
r"'\''",
"'")
296 if value
not in (
'False',
'True'):
297 raise ValueError(
'incorrect bool value %s' % value)
298 return value ==
'True'
299 return argtype(value)
308 if isinstance(value, str):
309 return "'" + value.replace(
"'",
r"'\''") +
"'"
315 print(_info[
'help'], file = sys.stderr)
318 print(
'this is %s version %s\n' % (pname, _info[
'version']), file = sys.stderr)
320 print(
'this is %s\n' % pname, file = sys.stderr)
322 print(
'\nSupported option arguments:', file = sys.stderr)
323 for module
in (
False,
True):
324 for opt
in option_order:
325 option = options[opt]
326 if (option[
'module']
is not None) != module:
328 m =
' (This option can be passed multiple times)' if option[
'multiple']
else ''
329 if option[
'argtype']
is bool:
331 if option[
'short']
is not None:
332 optname +=
', -' + option[
'short']
333 print(
'\t%s\n\t\t%s%s' % (optname, option[
'help'], m), file = sys.stderr)
334 elif option[
'optional']:
335 optname =
'--' + opt +
'[=<value>]'
336 if option[
'short']
is not None:
337 optname +=
', -' + option[
'short'] +
'[<value>]'
338 default =
' Default: %s' % str(option[
'default'])
if option[
'default']
is not None else ''
339 print(
'\t%s\n\t\t%s%s%s' % (optname, option[
'help'], default, m), file = sys.stderr)
341 optname =
'--' + opt +
'=<value>'
342 if option[
'short']
is not None:
343 optname +=
', -' + option[
'short'] +
'<value>'
344 default =
' Default: %s' % str(option[
'default'])
if option[
'default']
is not None else ''
345 print(
'\t%s\n\t\t%s%s%s' % (optname, option[
'help'], default, m), file = sys.stderr)
347 if _info[
'contact']
is not None:
348 print(
'\nPlease send feedback and bug reports to %s' % _info[
'contact'], file = sys.stderr)
353 print(
'%s version %s' % (pname, _info[
'version']), file = sys.stderr)
355 print(
'%s' % pname, file = sys.stderr)
357 print(
'\tPlease send feedback and bug reports to %s' % _info[
'contact'], file = sys.stderr)
359 if len(_module_info) > 0:
360 print(
'\nUsing modules:', file = sys.stderr)
361 for mod
in _module_info:
362 print(
'\t%s version %s\n\t\t%s' % (mod, _module_info[mod][
'version'], _module_info[mod][
'desc']), file = sys.stderr)
363 if _module_info[mod][
'contact']
is not None:
364 print(
'\t\tPlease send feedback and bug reports for %s to %s' % (mod, _module_info[mod][
'contact']), file = sys.stderr)
367def load_config(filename, values = None, present = None, options = None):
379 if cfg.strip() ==
'' or cfg.strip().startswith(
'#'):
382 print(
'invalid line in config file %s: %s' % (filename, cfg), file = sys.stderr)
383 key, value = cfg.split(
'=', 1)
384 key = _unprotect(key)
385 if not new_values
and key
not in values:
386 print(
'invalid key %s in config file' % key, file = sys.stderr)
388 if key
in present
and present[key]:
391 if options
is not None and options[key][
'multiple']:
392 values[key] = [
decode_value(_unprotect(v), options[key][
'argtype'])
for v
in value.split(
',')]
394 values[key] = _unprotect(value)
if options
is None else decode_value(_unprotect(value), options[key][
'argtype'])
396 print(
'Warning: error loading value for %s; ignoring' % key, file = sys.stderr)
398 if present
is not None:
415 filename =
'commandline' + os.extsep +
'ini'
417 filename = name + os.extsep +
'ini'
418 keys = list(config.keys())
422 if isinstance(config[key], list):
423 value =
','.join(_protect(
encode_value(x),
',')
for x
in config[key])
426 f.write(
'%s=%s\n' % (_protect(key,
'='), value))
448def option(name, help, short = None, multiple = False, optional = False, default = None, noarg = None, argtype = None, module = None, options = None, option_order = None):
450 assert not initialized
452 if option_order
is None:
453 option_order = _option_order
455 raise ValueError(
'duplicate registration of argument name %s' % name)
456 if not isinstance(name, str)
or len(name) == 0
or name.startswith(
'-'):
457 raise ValueError(
'argument must not start with "-": %s' % name)
458 if short
is not None:
459 if any(options[x][
'short'] == short
for x
in options):
460 raise ValueError(
'duplicate short option %s defined' % short)
462 raise ValueError(
'length of short option %s for %s must be 1' % (short, name))
464 raise ValueError(
'short option for %s cannot be "-"' % name)
466 if default
is not None:
467 argtype = type(default)
471 if default
is None and noarg
is None:
472 default, noarg =
False,
True
475 if not isinstance(noarg, bool):
476 raise ValueError(
'noarg value for %s must be of type bool if argtype is bool' % name)
481 raise ValueError(
'noarg value %s for %s changes when saving to config file' % (str(noarg), name))
483 raise ValueError(
'noarg value %s for %s cannot be restored from config file' % (str(noarg), name))
484 options[name] = {
'help': help,
'short': short,
'multiple': multiple,
'optional': optional,
'default': default,
'noarg': noarg,
'argtype': argtype,
'module': module}
485 option_order.append(name)
494 shorts = {options[name][
'short']: name
for name
in options}
495 values = {name: []
if options[name][
'multiple']
else options[name][
'default']
for name
in options}
496 present = {name:
False for name
in options}
498 while pos < len(argv):
500 nextarg = argv[pos + 1]
if pos + 1 < len(argv)
else None
504 if len(current) < 2
or not current.startswith(
'-'):
507 if current.startswith(
'--'):
510 optname, arg = current.split(
'=', 1)
512 optname, arg = current,
None
513 optname = optname[2:]
514 if optname
not in options:
515 print(
'Warning: ignoring unrecognized option %s' % optname)
518 opt = options[optname]
519 argtype = opt[
'argtype']
523 elif opt[
'optional']:
526 value = opt[
'argtype'](arg)
532 value = opt[
'argtype'](arg)
536 print(
'Warning: option %s requires an argument' % optname, file = sys.stderr)
538 value = opt[
'argtype'](argv[pos])
540 values[optname].append(value)
543 print(
'Warning: option %s must only be passed once' % optname, file = sys.stderr)
544 values[optname] = value
545 present[optname] =
True
549 while optpos < len(current):
553 print(
'Warning: short option %s is not recognized' % o, file = sys.stderr)
556 opt = options[optname]
557 argtype = opt[
'argtype']
561 elif opt[
'optional']:
563 if optpos < len(current):
564 value = opt[
'argtype'](current[optpos:])
567 optpos = len(current)
570 if optpos < len(current):
571 value = opt[
'argtype'](current[optpos:])
575 print(
'Warning: option %s (%s) requires an argument' % (o, optname), file = sys.stderr)
577 value = opt[
'argtype'](argv[pos])
578 optpos = len(current)
580 values[optname].append(value)
583 print(
'Warning: option %s (%s) must only be passed once' % (o, optname), file = sys.stderr)
584 values[optname] = value
585 present[optname] =
True
588 return values, present
615def init(config = None, help = None, version = None, contact = None, packagename = None, system = None, game = False):
617 assert not initialized
619 if packagename
is not None:
624 if config
is not None:
625 print(
'Warning: using the config parameter for fhs.init() is DEPRECATED! Use option() instead.', file = sys.stderr)
627 option(key,
'no help for this option', default = config[key])
628 global XDG_RUNTIME_DIR
629 global _values, _present
634 _info = {
'help': help,
'version': version,
'contact': contact}
638 option(
'help',
'Show this help text', short =
None if any(_options[o][
'short'] ==
'h' for o
in _options)
else 'h', argtype = bool, options = first_options, option_order = option_order)
639 option(
'version',
'Show version information', short =
None if any(_options[o][
'short'] ==
'v' for o
in _options)
else 'v', argtype = bool, options = first_options, option_order = option_order)
640 option(
'configfile',
'Use this file for loading and/or saving commandline configuration', default =
'commandline', options = first_options, option_order = option_order)
641 option(
'saveconfig',
'Save active commandline configuration as default or to the named file', optional =
True, default =
None, noarg =
'', argtype = str, options = first_options, option_order = option_order)
643 option(
'system',
'Use only system paths', argtype = bool, options = first_options, option_order = option_order)
646 options = first_options.copy()
647 options.update(_options)
648 option_order += _option_order
650 _values, _present =
parse_args(sys.argv, options, extra =
True)
651 except ValueError
as err:
653 print(
'Error parsing arguments: %s' % str(err))
660 if _values[
'version']:
663 _values.pop(
'version')
664 configfile = _values.pop(
'configfile')
665 saveconfig = _values.pop(
'saveconfig')
667 is_system = _values[
'system']
671 saveconfig = configfile
672 load_config(configfile, _values, _present, options)
673 if saveconfig
is not None:
674 save_config({key: _values[key]
for key
in _values
if _present[key]}, saveconfig, packagename)
676 for module
in _module_config:
677 _module_values[module] = {key: _values.pop(module +
'-' + key)
for key
in _module_config[module]}
678 _module_present[module] = {key: _present.pop(module +
'-' + key)
for key
in _module_config[module]}
683 is_system = _values.pop(
'system')
690 shutil.rmtree(f, ignore_errors =
True)
691 if XDG_RUNTIME_DIR
is None:
709 print(
'Warning: init() should be called before get_config() to set program information', file = sys.stderr)
712 return _values, _present;
727 assert not initialized
728 if modulename
in _module_info:
729 print(
'Warning: duplicate registration of information for module %s' % modulename, file = sys.stderr)
731 _module_info[modulename] = {
'desc': desc,
'version': version,
'contact': contact}
732 _module_config[modulename] = set()
740def module_option(modulename, name, help, short = None, multiple = False, optional = False, default = None, noarg = None, argtype = None, options = None, option_order = None):
741 assert not initialized
742 assert modulename
in _module_info
743 _module_config[modulename].add(name)
744 return option(modulename +
'-' + name, help, short, multiple, optional, default, noarg, argtype, modulename, options, option_order)
758 print(
'Warning: module %s uses module_init() which is DEPRECATED! It should use module_option() instead.' % modulename, file = sys.stderr)
759 assert not initialized
760 module_info(modulename,
'no information about this module available',
'unknown',
None)
762 module_option(modulename, key,
'no help for this module option', default = config[key])
780 return _module_values[modulename], _module_present[modulename];
782 return _module_values[modulename];
789XDG_RUNTIME_DIR = os.getenv(
'XDG_RUNTIME_DIR')
790def _runtime_get(name, packagename, dir):
794 name = packagename
or pname
796 name = (packagename
or pname) + os.extsep +
'txt'
798 name = os.path.join(packagename
or pname, name)
799 d =
'/run' if is_system
else XDG_RUNTIME_DIR
800 target = os.path.join(d, name)
801 d = target
if dir
else os.path.dirname(target)
812def write_runtime(name = None, text = True, dir = False, opened = True, packagename = None):
813 d, target = _runtime_get(name, packagename, dir)
814 if opened
and not os.path.exists(d):
816 return open(target,
'w+' if text
else 'w+b')
if opened
and not dir
else target
826def read_runtime(name = None, text = True, dir = False, opened = True, packagename = None):
827 d, target = _runtime_get(name, packagename, dir)
828 if os.path.exists(target)
and (dir
if os.path.isdir(target)
else not dir):
829 return open(target,
'r' if text
else 'rb')
if opened
and not dir
else target
842 shutil.rmtree(
read_runtime(name,
False,
True,
False, packagename), ignore_errors =
False)
844 os.unlink(
read_runtime(name,
False,
False,
False, packagename))
849 def __init__(self, f, name):
851 super().__setattr__(
'_file', f)
852 super().__setattr__(
'filename', name)
855 assert self.filename
is not None
857 os.unlink(self.filename)
858 _tempfiles.remove(self.filename)
859 super().__setattr__(
'_file',
None)
860 super().__setattr__(
'filename',
None)
861 def __getattr__(self, k):
862 return getattr(self._file, k)
863 def __setattr__(self, k, v):
864 return setattr(self._file, k, v)
867 def __exit__(self, exc_type, exc_value, traceback):
895 ret = tempfile.mkdtemp(prefix = (packagename
or pname) +
'-')
896 _tempfiles.append(ret)
898 f = tempfile.mkstemp(text = text, prefix = (packagename
or pname) +
'-')
899 _tempfiles.append(f[1])
900 ret = _TempFile(os.fdopen(f[0],
'w+' if text
else 'w+b'), f[1])
912 assert name
in _tempfiles
913 _tempfiles.remove(name)
914 shutil.rmtree(name, ignore_errors =
False)
919XDG_DATA_HOME = os.getenv(
'XDG_DATA_HOME', os.path.join(HOME,
'.local',
'share'))
921XDG_DATA_DIRS = os.getenv(
'XDG_DATA_DIRS',
'/usr/local/share:/usr/share').split(
':')
931def write_data(name = None, text = True, dir = False, opened = True, packagename = None):
935 filename = packagename
or pname
937 filename = (packagename
or pname) + os.extsep +
'dat'
939 filename = name
if is_system
else os.path.join(packagename
or pname, name)
942 if packagename
and packagename != pname:
943 d = os.path.join(
'/var/games', pname, packagename)
945 d = os.path.join(
'/var/games', pname)
947 if packagename
and packagename != pname:
948 d = os.path.join(
'/var/lib', pname, packagename)
950 d = os.path.join(
'/var/lib', pname)
953 target = os.path.join(d, filename)
955 if opened
and not os.path.exists(target):
959 d = os.path.dirname(target)
960 if opened
and not os.path.exists(d):
962 return open(target,
'w+' if text
else 'w+b')
if opened
else target
972def read_data(name = None, text = True, dir = False, multiple = False, opened = True, packagename = None):
976 filename = packagename
or pname
978 filename = (packagename
or pname) + os.extsep +
'dat'
984 t = os.path.join(XDG_DATA_HOME, filename
if name
is None else os.path.join(packagename
or pname, name))
985 if os.path.realpath(t)
not in seen
and os.path.exists(t)
and (dir
if os.path.isdir(t)
else not dir):
986 r = t
if dir
or not opened
else open(t,
'r' if text
else 'rb')
989 seen.add(os.path.realpath(t))
991 dirs = [
'/var/local/lib',
'/var/lib',
'/usr/local/lib',
'/usr/lib',
'/usr/local/share',
'/usr/share']
993 dirs = [
'/var/local/games',
'/var/games',
'/usr/local/lib/games',
'/usr/lib/games',
'/usr/local/share/games',
'/usr/share/games'] + dirs
995 for d
in XDG_DATA_DIRS[::-1]:
997 if packagename
and packagename != pname:
998 dirs = [os.path.join(x, pname, packagename)
for x
in dirs] + [os.path.join(x, packagename)
for x
in dirs]
1000 dirs = [os.path.join(x, pname)
for x
in dirs]
1002 dirs.insert(0, packagename
or pname)
1003 dirs.insert(0, os.path.curdir)
1004 dirs.insert(0, _base)
1006 t = os.path.join(d, filename)
1007 if os.path.realpath(t)
not in seen
and os.path.exists(t)
and (dir
if os.path.isdir(t)
else not dir):
1008 r = t
if dir
or not opened
else open(t,
'r' if text
else 'rb')
1011 seen.add(os.path.realpath(t))
1027 shutil.rmtree(
read_data(name,
False,
True,
False,
False, packagename), ignore_errors =
False)
1029 os.unlink(
read_data(name,
False,
False,
False,
False, packagename))
1034XDG_CACHE_HOME = os.getenv(
'XDG_CACHE_HOME', os.path.join(HOME,
'.cache'))
1044def write_cache(name = None, text = True, dir = False, opened = True, packagename = None):
1048 filename = packagename
or pname
1050 filename = (packagename
or pname) + os.extsep +
'dat'
1052 filename = name
if is_system
else os.path.join(packagename
or pname, name)
1053 d = os.path.join(
'/var/cache', packagename
or pname)
if is_system
else XDG_CACHE_HOME
1054 target = os.path.join(d, filename)
1056 if opened
and not os.path.exists(target):
1060 d = os.path.dirname(target)
1061 if opened
and not os.path.exists(d):
1063 return open(target,
'w+' if text
else 'w+b')
if opened
and not dir
else target
1073def read_cache(name = None, text = True, dir = False, opened = True, packagename = None):
1077 filename = packagename
or pname
1079 filename = (packagename
or pname) + os.extsep +
'dat'
1081 filename = os.path.join(packagename
or pname, name)
1082 target = os.path.join(XDG_CACHE_HOME, filename)
1083 if not os.path.exists(target):
1085 filename = os.path.join(packagename
or pname, packagename
or pname + os.extsep +
'dat')
1087 target = os.path.join(d, filename)
1088 if not os.path.exists(target):
1090 return open(target,
'r' if text
else 'rb')
if opened
and not dir
else target
1101 shutil.rmtree(
read_cache(name,
False,
True,
False, packagename), ignore_errors =
False)
1103 os.unlink(
read_cache(name,
False,
False,
False, packagename))
1120 filename = (packagename
or pname) + os.extsep +
'log'
1122 filename = os.path.join(packagename
or pname, name)
1123 target = os.path.join(
'/var/log', filename)
1124 d = os.path.dirname(target)
1125 if not os.path.exists(d):
1127 return open(target,
'a')
1141def write_spool(name = None, text = True, dir = False, opened = True, packagename = None):
1145 filename = packagename
or pname
1147 filename = (packagename
or pname) + os.extsep +
'dat'
1149 filename = os.path.join(packagename
or pname, name)
1150 target = os.path.join(
'/var/spool' if is_system
else os.path.join(XDG_CACHE_HOME,
'spool'), filename)
1151 d = os.path.dirname(target)
1152 if opened
and not os.path.exists(d):
1154 return open(target,
'w+' if text
else 'w+b')
if opened
and not dir
else target
1164def read_spool(name = None, text = True, dir = False, opened = True, packagename = None):
1168 filename = packagename
or pname
1170 filename = (packagename
or pname) + os.extsep +
'dat'
1172 filename = os.path.join(packagename
or pname, name)
1173 target = os.path.join(
'/var/spool' if is_system
else os.path.join(XDG_CACHE_HOME,
'spool'), filename)
1174 if not os.path.exists(target):
1176 return open(target,
'r' if text
else 'rb')
if opened
and not dir
else target
1188 filename = packagename
or pname
1190 filename = (packagename
or pname) + os.extsep +
'dat'
1192 shutil.rmtree(
read_spool(name,
False,
True,
False, packagename), ignore_errors =
False)
1194 os.unlink(
read_spool(name,
False,
False,
False, packagename))
1201def lock(name = None, info = '', packagename = None):
def write_data(name=None, text=True, dir=False, opened=True, packagename=None)
Open a data file for writing.
def read_cache(name=None, text=True, dir=False, opened=True, packagename=None)
Open a cache file for reading.
def read_config(name=None, text=True, dir=False, multiple=False, opened=True, packagename=None)
Open a config file for reading.
def read_spool(name=None, text=True, dir=False, opened=True, packagename=None)
Open a spool file for reading.
def module_init(modulename, config)
Add configuration for a module.
def parse_args(argv=None, options=None, extra=False)
def write_temp(dir=False, text=True, packagename=None)
Open a temporary file for writing.
def save_config(config, name=None, packagename=None)
Save a dict as a configuration file.
def read_runtime(name=None, text=True, dir=False, opened=True, packagename=None)
Open a runtime file for reading.
def write_config(name=None, text=True, dir=False, opened=True, packagename=None)
Open a config file for writing.
def write_cache(name=None, text=True, dir=False, opened=True, packagename=None)
Open a cache file for writing.
def remove_cache(name=None, dir=False, packagename=None)
Remove a cache file.
def unlock(name=None, packagename=None)
Release a lock.
def remove_data(name=None, dir=False, packagename=None)
Remove a data file.
def read_data(name=None, text=True, dir=False, multiple=False, opened=True, packagename=None)
Open a data file for reading.
def write_runtime(name=None, text=True, dir=False, opened=True, packagename=None)
Open a runtime file for writing.
def init(config=None, help=None, version=None, contact=None, packagename=None, system=None, game=False)
Initialize the module.
def load_config(filename, values=None, present=None, options=None)
def remove_temp(name)
Remove a temporary directory.
def decode_value(value, argtype)
Parse a string value into its proper type.
def module_option(modulename, name, help, short=None, multiple=False, optional=False, default=None, noarg=None, argtype=None, options=None, option_order=None)
Register a commandline option for a module.
def write_log(name=None, packagename=None)
Open a log file for writing.
def lock(name=None, info='', packagename=None)
Acquire a lock.
def module_info(modulename, desc, version, contact)
Register information about a module.
def help_text(main, options, option_order)
def module_get_config(modulename, extra=False)
Retrieve module configuration.
def get_config(extra=False)
Retrieve commandline configuration.
def write_spool(name=None, text=True, dir=False, opened=True, packagename=None)
Open a spool file for writing.
def remove_runtime(name=None, dir=False, packagename=None)
Remove a reuntime file or directory.
def remove_config(name=None, dir=False, packagename=None)
Remove a config file.
def remove_spool(name=None, dir=False, packagename=None)
Remove a spool file.
def encode_value(value)
Encode a value into a string which can be stored in a config file.
def option(name, help, short=None, multiple=False, optional=False, default=None, noarg=None, argtype=None, module=None, options=None, option_order=None)
Register commandline argument.