python: cleanup options parsing stuff so that it properly deals with defaults.
While we're at it, make it possible to run main.py in a somewhat standalone mode again so that we can test things without compiling.
This commit is contained in:
parent
6c046a28dc
commit
6b2bb53fd6
|
@ -34,9 +34,7 @@ import sys
|
||||||
|
|
||||||
from util import attrdict
|
from util import attrdict
|
||||||
import config
|
import config
|
||||||
import defines
|
|
||||||
from options import OptionParser
|
from options import OptionParser
|
||||||
import traceflags
|
|
||||||
|
|
||||||
__all__ = [ 'options', 'arguments', 'main' ]
|
__all__ = [ 'options', 'arguments', 'main' ]
|
||||||
|
|
||||||
|
@ -132,7 +130,6 @@ add_option("--list-sim-objects", action='store_true', default=False,
|
||||||
help="List all built-in SimObjects, their parameters and default values")
|
help="List all built-in SimObjects, their parameters and default values")
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
import defines
|
|
||||||
import event
|
import event
|
||||||
import info
|
import info
|
||||||
import internal
|
import internal
|
||||||
|
@ -176,6 +173,8 @@ def main():
|
||||||
done = False
|
done = False
|
||||||
|
|
||||||
if options.build_info:
|
if options.build_info:
|
||||||
|
import defines
|
||||||
|
|
||||||
done = True
|
done = True
|
||||||
print 'Build information:'
|
print 'Build information:'
|
||||||
print
|
print
|
||||||
|
@ -217,6 +216,8 @@ def main():
|
||||||
print
|
print
|
||||||
|
|
||||||
if options.trace_help:
|
if options.trace_help:
|
||||||
|
import traceflags
|
||||||
|
|
||||||
done = True
|
done = True
|
||||||
print "Base Flags:"
|
print "Base Flags:"
|
||||||
print_list(traceflags.baseFlags, indent=4)
|
print_list(traceflags.baseFlags, indent=4)
|
||||||
|
@ -297,27 +298,30 @@ def main():
|
||||||
for when in options.debug_break:
|
for when in options.debug_break:
|
||||||
internal.debug.schedBreakCycle(int(when))
|
internal.debug.schedBreakCycle(int(when))
|
||||||
|
|
||||||
on_flags = []
|
if options.trace_flags:
|
||||||
off_flags = []
|
import traceflags
|
||||||
for flag in options.trace_flags:
|
|
||||||
off = False
|
|
||||||
if flag.startswith('-'):
|
|
||||||
flag = flag[1:]
|
|
||||||
off = True
|
|
||||||
if flag not in traceflags.allFlags:
|
|
||||||
print >>sys.stderr, "invalid trace flag '%s'" % flag
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
if off:
|
on_flags = []
|
||||||
off_flags.append(flag)
|
off_flags = []
|
||||||
else:
|
for flag in options.trace_flags:
|
||||||
on_flags.append(flag)
|
off = False
|
||||||
|
if flag.startswith('-'):
|
||||||
|
flag = flag[1:]
|
||||||
|
off = True
|
||||||
|
if flag not in traceflags.allFlags:
|
||||||
|
print >>sys.stderr, "invalid trace flag '%s'" % flag
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
for flag in on_flags:
|
if off:
|
||||||
internal.trace.set(flag)
|
off_flags.append(flag)
|
||||||
|
else:
|
||||||
|
on_flags.append(flag)
|
||||||
|
|
||||||
for flag in off_flags:
|
for flag in on_flags:
|
||||||
internal.trace.clear(flag)
|
internal.trace.set(flag)
|
||||||
|
|
||||||
|
for flag in off_flags:
|
||||||
|
internal.trace.clear(flag)
|
||||||
|
|
||||||
if options.trace_start:
|
if options.trace_start:
|
||||||
def enable_trace():
|
def enable_trace():
|
||||||
|
@ -358,7 +362,14 @@ def main():
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
from pprint import pprint
|
from pprint import pprint
|
||||||
|
|
||||||
parse_args()
|
# load the options.py config file to allow people to set their own
|
||||||
|
# default options
|
||||||
|
options_file = config.get('options.py')
|
||||||
|
if options_file:
|
||||||
|
scope = { 'options' : options }
|
||||||
|
execfile(options_file, scope)
|
||||||
|
|
||||||
|
arguments = options.parse_args()
|
||||||
|
|
||||||
print 'opts:'
|
print 'opts:'
|
||||||
pprint(options, indent=4)
|
pprint(options, indent=4)
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
|
|
||||||
import optparse
|
import optparse
|
||||||
import sys
|
import sys
|
||||||
import util
|
|
||||||
|
|
||||||
from optparse import *
|
from optparse import *
|
||||||
|
|
||||||
|
@ -45,19 +44,20 @@ class splitter(object):
|
||||||
else:
|
else:
|
||||||
dest.extend(values)
|
dest.extend(values)
|
||||||
|
|
||||||
class OptionParser(object):
|
class OptionParser(dict):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
kwargs.setdefault('formatter', optparse.TitledHelpFormatter())
|
kwargs.setdefault('formatter', optparse.TitledHelpFormatter())
|
||||||
self._optparse = optparse.OptionParser(*args, **kwargs)
|
self._optparse = optparse.OptionParser(*args, **kwargs)
|
||||||
self._optparse.disable_interspersed_args()
|
self._optparse.disable_interspersed_args()
|
||||||
|
|
||||||
self._allopts = {}
|
self._allopts = {}
|
||||||
self._defaults = {}
|
|
||||||
self._options = util.attrdict()
|
|
||||||
|
|
||||||
# current option group
|
# current option group
|
||||||
self._group = self._optparse
|
self._group = self._optparse
|
||||||
|
|
||||||
|
def set_defaults(self, *args, **kwargs):
|
||||||
|
return self._optparse.set_defaults(*args, **kwargs)
|
||||||
|
|
||||||
def set_group(self, *args, **kwargs):
|
def set_group(self, *args, **kwargs):
|
||||||
'''set the current option group'''
|
'''set the current option group'''
|
||||||
if not args and not kwargs:
|
if not args and not kwargs:
|
||||||
|
@ -78,16 +78,11 @@ class OptionParser(object):
|
||||||
kwargs['action'] = 'callback'
|
kwargs['action'] = 'callback'
|
||||||
kwargs['callback'] = splitter(split)
|
kwargs['callback'] = splitter(split)
|
||||||
|
|
||||||
default = kwargs.pop('default', nodefault)
|
|
||||||
option = self._group.add_option(*args, **kwargs)
|
option = self._group.add_option(*args, **kwargs)
|
||||||
dest = option.dest
|
dest = option.dest
|
||||||
if dest not in self._allopts:
|
if dest not in self._allopts:
|
||||||
self._allopts[dest] = option
|
self._allopts[dest] = option
|
||||||
|
|
||||||
if default != nodefault:
|
|
||||||
if dest not in self._options:
|
|
||||||
self._options[dest] = default
|
|
||||||
|
|
||||||
return option
|
return option
|
||||||
|
|
||||||
def bool_option(self, name, default, help):
|
def bool_option(self, name, default, help):
|
||||||
|
@ -113,28 +108,30 @@ class OptionParser(object):
|
||||||
|
|
||||||
def __getattr__(self, attr):
|
def __getattr__(self, attr):
|
||||||
if attr.startswith('_'):
|
if attr.startswith('_'):
|
||||||
return super(OptionParser, self).__getattr__(attr)
|
return super(OptionParser, self).__getattribute__(attr)
|
||||||
|
|
||||||
if attr in self._options:
|
if attr in self:
|
||||||
return self._options[attr]
|
return self[attr]
|
||||||
|
|
||||||
raise AttributeError, "Option %s not found" % attr
|
return super(OptionParser, self).__getattribute__(attr)
|
||||||
|
|
||||||
def __setattr__(self, attr, value):
|
def __setattr__(self, attr, value):
|
||||||
if attr.startswith('_'):
|
if attr.startswith('_'):
|
||||||
return super(OptionParser, self).__setattr__(attr, value)
|
super(OptionParser, self).__setattr__(attr, value)
|
||||||
|
elif attr in self._allopts:
|
||||||
if attr in self._options:
|
defaults = { attr : value }
|
||||||
self._options[attr] = value
|
self.set_defaults(**defaults)
|
||||||
|
if attr in self:
|
||||||
return super(OptionParser, self).__setattr__(attr, value)
|
self[attr] = value
|
||||||
|
else:
|
||||||
|
super(OptionParser, self).__setattr__(attr, value)
|
||||||
|
|
||||||
def parse_args(self):
|
def parse_args(self):
|
||||||
opts,args = self._optparse.parse_args()
|
opts,args = self._optparse.parse_args()
|
||||||
|
|
||||||
for key,val in opts.__dict__.iteritems():
|
for key,val in opts.__dict__.iteritems():
|
||||||
if val is not None or key not in self._options:
|
if val is not None or key not in self:
|
||||||
self._options[key] = val
|
self[key] = val
|
||||||
|
|
||||||
return args
|
return args
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue