You can subscribe to this list here.
2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(13) |
Jul
(13) |
Aug
(17) |
Sep
|
Oct
(9) |
Nov
(1) |
Dec
(5) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2003 |
Jan
|
Feb
|
Mar
|
Apr
(27) |
May
(10) |
Jun
(6) |
Jul
(1) |
Aug
(3) |
Sep
(6) |
Oct
|
Nov
(1) |
Dec
|
2004 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
(9) |
Jun
(26) |
Jul
(23) |
Aug
(2) |
Sep
(7) |
Oct
|
Nov
|
Dec
|
2006 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Greg W. <gw...@us...> - 2004-06-02 01:51:34
|
Update of /cvsroot/optik/optik/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10205 Modified Files: option.py Log Message: SF #960515: fix _check_dest() so it generates 'dest' for any option that specifies a type -- needed for callbacks where the developer has specified 'type' but not 'dest' or 'metavar'. Index: option.py =================================================================== RCS file: /cvsroot/optik/optik/lib/option.py,v retrieving revision 1.28 retrieving revision 1.29 diff -u -d -r1.28 -r1.29 --- option.py 2 Jun 2004 00:08:24 -0000 1.28 +++ option.py 2 Jun 2004 01:51:24 -0000 1.29 @@ -259,8 +259,12 @@ "must not supply choices for type %r" % self.type, self) def _check_dest(self): - if self.action in self.STORE_ACTIONS and self.dest is None: - # No destination given, and we need one for this action. + # No destination given, and we need one for this action. The + # self.type check is for callbacks that take a value. + takes_value = (self.action in self.STORE_ACTIONS or + self.type is not None) + if self.dest is None and takes_value: + # Glean a destination from the first long option string, # or from the first short option string if no long options. if self._long_opts: |
From: Greg W. <gw...@us...> - 2004-06-02 01:29:32
|
Update of /cvsroot/optik/optik/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6922 Modified Files: option_parser.py Log Message: Fix OptionParser.get_default_values() so it makes a copy of self.defaults before processing default values. Index: option_parser.py =================================================================== RCS file: /cvsroot/optik/optik/lib/option_parser.py,v retrieving revision 1.61 retrieving revision 1.62 diff -u -d -r1.61 -r1.62 --- option_parser.py 2 Jun 2004 00:16:42 -0000 1.61 +++ option_parser.py 2 Jun 2004 01:29:22 -0000 1.62 @@ -476,7 +476,7 @@ # Old, pre-Optik 1.5 behaviour. return Values(self.defaults) - defaults = self.defaults + defaults = self.defaults.copy() for option in self._get_all_options(): default = defaults.get(option.dest) if isinstance(default, basestring): |
From: Greg W. <gw...@us...> - 2004-06-02 00:20:59
|
Update of /cvsroot/optik/optik/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26555 Modified Files: test_optik.py Log Message: SF #955889: refactor TestDefaultValues a bit (add 'expected' attribute). Add test_process_default() to test the new behaviour of OptionParser.get_default_values(), as well as the ability to revert to the old behaviour. Add an assert to test_mixed_defaults_pre(). Index: test_optik.py =================================================================== RCS file: /cvsroot/optik/optik/test/test_optik.py,v retrieving revision 1.25 retrieving revision 1.26 diff -u -d -r1.25 -r1.26 --- test_optik.py 1 Jun 2004 02:04:55 -0000 1.25 +++ test_optik.py 2 Jun 2004 00:20:47 -0000 1.26 @@ -328,6 +328,24 @@ self.assertRaises(self.parser.remove_option, ValueError, "no such option 'foo'", funcargs=['foo']) +# Custom type for testing processing of default values. +_time_units = { 's' : 1, 'm' : 60, 'h' : 60*60, 'd' : 60*60*24 } + +def _check_duration(option, opt, value): + try: + if value[-1].isdigit(): + return int(value) + else: + return int(value[:-1]) * _time_units[value[-1]] + except ValueError, IndexError: + raise OptionValueError( + 'option %s: invalid duration: %r' % (opt, value)) + +class DurationOption(Option): + TYPES = Option.TYPES + ('duration',) + TYPE_CHECKER = copy.copy(Option.TYPE_CHECKER) + TYPE_CHECKER['duration'] = _check_duration + class TestDefaultValues(BaseTest): def setUp(self): self.parser = OptionParser() @@ -338,39 +356,46 @@ self.parser.add_option("-s", default="foo") self.parser.add_option("-t") self.parser.add_option("-u", default=None) + self.expected = { 'verbose': True, + 'n': 37, + 'm': None, + 's': "foo", + 't': None, + 'u': None } def test_basic_defaults(self): - self.assertEqual(self.parser.get_default_values(), - { 'verbose': True, - 'n': 37, - 'm': None, - 's': "foo", - 't': None, - 'u': None }) + self.assertEqual(self.parser.get_default_values(), self.expected) def test_mixed_defaults_post(self): self.parser.set_defaults(n=42, m=-100) - self.assertEqual(self.parser.get_default_values(), - { 'verbose': True, - 'n': 42, - 'm': -100, - 's': "foo", - 't': None, - 'u': None }) + self.expected.update({'n': 42, 'm': -100}) + self.assertEqual(self.parser.get_default_values(), self.expected) def test_mixed_defaults_pre(self): self.parser.set_defaults(x="barf", y="blah") self.parser.add_option("-x", default="frob") self.parser.add_option("-y") - self.assertEqual(self.parser.get_default_values(), - { 'verbose': True, - 'n': 37, - 'm': None, - 's': "foo", - 'u': None, - 't': None, - 'x': "frob", - 'y': "blah" }) + + self.expected.update({'x': "frob", 'y': "blah"}) + self.assertEqual(self.parser.get_default_values(), self.expected) + + self.parser.remove_option("-y") + self.parser.add_option("-y", default=None) + self.expected.update({'y': None}) + self.assertEqual(self.parser.get_default_values(), self.expected) + + def test_process_default(self): + self.parser.option_class = DurationOption + self.parser.add_option("-d", type="duration", default=300) + self.parser.add_option("-e", type="duration", default="6m") + self.parser.set_defaults(n="42") + self.expected.update({'d': 300, 'e': 360, 'n': 42}) + self.assertEqual(self.parser.get_default_values(), self.expected) + + self.parser.set_process_default_values(False) + self.expected.update({'d': 300, 'e': "6m", 'n': "42"}) + self.assertEqual(self.parser.get_default_values(), self.expected) + class TestProgName(BaseTest): """ |
From: Greg W. <gw...@us...> - 2004-06-02 00:16:53
|
Update of /cvsroot/optik/optik/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25841 Modified Files: option_parser.py Log Message: Define True/False locally (for compatibility with Python 2.2), and use them instead of 1/0. Index: option_parser.py =================================================================== RCS file: /cvsroot/optik/optik/lib/option_parser.py,v retrieving revision 1.60 retrieving revision 1.61 diff -u -d -r1.60 -r1.61 --- option_parser.py 2 Jun 2004 00:13:21 -0000 1.60 +++ option_parser.py 2 Jun 2004 00:16:42 -0000 1.61 @@ -25,6 +25,10 @@ # For compatibility with Python 2.2 try: + True, False +except NameError: + (True, False) = (1, 0) +try: basestring except NameError: basestring = (str, unicode) @@ -375,7 +379,7 @@ conflict_handler="error", description=None, formatter=None, - add_help_option=1, + add_help_option=True, prog=None): OptionContainer.__init__( self, option_class, conflict_handler, description) @@ -416,7 +420,7 @@ action="version", help="show program's version number and exit") - def _populate_option_list(self, option_list, add_help=1): + def _populate_option_list(self, option_list, add_help=True): if self.standard_option_list: self.add_options(self.standard_option_list) if option_list: @@ -636,10 +640,10 @@ if "=" in arg: (opt, next_arg) = arg.split("=", 1) rargs.insert(0, next_arg) - had_explicit_value = 1 + had_explicit_value = True else: opt = arg - had_explicit_value = 0 + had_explicit_value = False opt = self._match_long_opt(opt) option = self._long_opt[opt] @@ -667,7 +671,7 @@ def _process_short_opts(self, rargs, values): arg = rargs.pop(0) - stop = 0 + stop = False i = 1 for ch in arg[1:]: opt = "-" + ch @@ -681,7 +685,7 @@ # next arg, and stop consuming characters of arg. if i < len(arg): rargs.insert(0, arg[i:]) - stop = 1 + stop = True nargs = option.nargs if len(rargs) < nargs: |
From: Greg W. <gw...@us...> - 2004-06-02 00:13:31
|
Update of /cvsroot/optik/optik/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25208 Modified Files: option_parser.py Log Message: SF #955889: change OptionParser.get_default_values() so it passes option default values that happen to be strings through the option's type-checking function. This allows developers to specify more natural defaults for options with custom types, which tends to produce better-looking help, eg. "(default: 5m)" rather than "(default: 300)". This can be reverted to Optik 1.4.1's behaviour by calling parser.set_process_default_values(False) -- added process_default_values instance attribute. Add OptionParser._get_all_options(). Document OptionParser.option_groups instance attribute. Add Values.__eq__() so we can compare a Values instance to a dict (handy in the test suite). Define basestring for backwards compatibility with Python 2.2. Use True/False instead of 1/0 in a few places. Index: option_parser.py =================================================================== RCS file: /cvsroot/optik/optik/lib/option_parser.py,v retrieving revision 1.59 retrieving revision 1.60 diff -u -d -r1.59 -r1.60 --- option_parser.py 29 May 2004 02:32:09 -0000 1.59 +++ option_parser.py 2 Jun 2004 00:13:21 -0000 1.60 @@ -23,6 +23,12 @@ SUPPRESS_HELP = "SUPPRESS"+"HELP" SUPPRESS_USAGE = "SUPPRESS"+"USAGE" +# For compatibility with Python 2.2 +try: + basestring +except NameError: + basestring = (str, unicode) + class Values: @@ -35,6 +41,14 @@ return ("<%s at 0x%x: %r>" % (self.__class__.__name__, id(self), self.__dict__)) + def __eq__(self, other): + if isinstance(other, Values): + return self.__dict__ == other.__dict__ + elif isinstance(other, dict): + return self.__dict__ == other + else: + return false + def _update_careful(self, dict): """ Update the option values from an arbitrary dictionary, but only @@ -305,7 +319,12 @@ the name of the current program (to override os.path.basename(sys.argv[0])). - allow_interspersed_args : boolean = true + option_groups : [OptionGroup] + list of option groups in this parser (option groups are + irrelevant for parsing the command-line, but very useful + for generating help) + + allow_interspersed_args : bool = true if true, positional arguments may be interspersed with options. Assuming -a and -b each take a single argument, the command-line -ablah foo bar -bboo baz @@ -318,6 +337,14 @@ Python's getopt module, Perl's Getopt::Std, and other argument- parsing libraries, but it is generally annoying to users.) + process_default_values : bool = true + if true, option default values are processed similarly to option + values from the command line: that is, they are passed to the + type-checking function for the option's type (as long as the + default value is a string). (This really only matters if you + have defined custom types; see SF bug #955889.) Set it to false + to restore the behaviour of Optik 1.4.1 and earlier. + rargs : [string] the argument list currently being parsed. Only set when parse_args() is active, and continually trimmed down as @@ -355,7 +382,8 @@ self.set_usage(usage) self.prog = prog self.version = version - self.allow_interspersed_args = 1 + self.allow_interspersed_args = True + self.process_default_values = True if formatter is None: formatter = IndentedHelpFormatter() self.formatter = formatter @@ -419,10 +447,13 @@ self.usage = usage def enable_interspersed_args(self): - self.allow_interspersed_args = 1 + self.allow_interspersed_args = True def disable_interspersed_args(self): - self.allow_interspersed_args = 0 + self.allow_interspersed_args = False + + def set_process_default_values(self, process): + self.process_default_values = process def set_default(self, dest, value): self.defaults[dest] = value @@ -430,8 +461,25 @@ def set_defaults(self, **kwargs): self.defaults.update(kwargs) + def _get_all_options(self): + options = self.option_list[:] + for group in self.option_groups: + options.extend(group.option_list) + return options + def get_default_values(self): - return Values(self.defaults) + if not self.process_default_values: + # Old, pre-Optik 1.5 behaviour. + return Values(self.defaults) + + defaults = self.defaults + for option in self._get_all_options(): + default = defaults.get(option.dest) + if isinstance(default, basestring): + opt_str = option.get_opt_string() + defaults[option.dest] = option.check_value(opt_str, default) + + return Values(defaults) # -- OptionGroup methods ------------------------------------------- |
From: Greg W. <gw...@us...> - 2004-06-02 00:08:41
|
Update of /cvsroot/optik/optik/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24251 Modified Files: option.py Log Message: SF #955889: factor convert_value() out of process(). Add get_opt_string() to return the first option string (prefer long, fallback to short). Make NO_DEFAULT a tuple rather than a string, since OptionParser.get_default_values() now treats strings specially. Index: option.py =================================================================== RCS file: /cvsroot/optik/optik/lib/option.py,v retrieving revision 1.27 retrieving revision 1.28 diff -u -d -r1.27 -r1.28 --- option.py 29 May 2004 02:32:09 -0000 1.27 +++ option.py 2 Jun 2004 00:08:24 -0000 1.28 @@ -47,7 +47,7 @@ # Not supplying a default is different from a default of None, # so we need an explicit "not supplied" value. -NO_DEFAULT = "NO"+"DEFAULT" +NO_DEFAULT = ("NO", "DEFAULT") class Option: @@ -329,6 +329,12 @@ def takes_value(self): return self.type is not None + def get_opt_string(self): + if self._long_opts: + return self._long_opts[0] + else: + return self._short_opts[0] + # -- Processing methods -------------------------------------------- @@ -339,15 +345,18 @@ else: return checker(self, opt, value) + def convert_value(self, opt, value): + if value is not None: + if self.nargs == 1: + return self.check_value(opt, value) + else: + return tuple([self.check_value(opt, v) for v in value]) + def process(self, opt, value, values, parser): # First, convert the value(s) to the right type. Howl if any # value(s) are bogus. - if value is not None: - if self.nargs == 1: - value = self.check_value(opt, value) - else: - value = tuple([self.check_value(opt, v) for v in value]) + value = self.convert_value(opt, value) # And then take whatever action is expected of us. # This is a separate method to make life easier for |
From: Greg W. <gw...@us...> - 2004-06-02 00:03:05
|
Update of /cvsroot/optik/optik/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23373 Modified Files: help.py Log Message: Oops, use identity comparison when comparing to NO_DEFAULT. Index: help.py =================================================================== RCS file: /cvsroot/optik/optik/lib/help.py,v retrieving revision 1.10 retrieving revision 1.11 diff -u -d -r1.10 -r1.11 --- help.py 29 May 2004 02:32:09 -0000 1.10 +++ help.py 2 Jun 2004 00:02:54 -0000 1.11 @@ -110,7 +110,7 @@ return option.help default_value = self.parser.defaults.get(option.dest) - if default_value in (NO_DEFAULT, None): + if default_value is NO_DEFAULT or default_value is None: default_value = self.NO_DEFAULT_VALUE return option.help.replace(self.default_tag, str(default_value)) |
From: Judy I. <jcp...@pa...> - 2004-06-01 21:24:30
|
mons widow roodscreen crosspatch feature misarrange quelled drinkable defeasible lose whining structure point kibbutznik jeep callithrix linecut vaseline sodoku gustatory clearway censorious sealing duchy satiable stuckup axinomancy reshape hemal |
From: Greg W. <gw...@us...> - 2004-06-01 02:05:03
|
Update of /cvsroot/optik/optik/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27501/test Modified Files: test_optik.py Log Message: Rename TestDefaultValues to TestExpandDefaults, because that's really what it's testing. Add TestDefaultValues to test that the right default values are included in the object returned by OptionParser.get_default_values(). Index: test_optik.py =================================================================== RCS file: /cvsroot/optik/optik/test/test_optik.py,v retrieving revision 1.24 retrieving revision 1.25 diff -u -d -r1.24 -r1.25 --- test_optik.py 29 May 2004 01:57:56 -0000 1.24 +++ test_optik.py 1 Jun 2004 02:04:55 -0000 1.25 @@ -328,6 +328,50 @@ self.assertRaises(self.parser.remove_option, ValueError, "no such option 'foo'", funcargs=['foo']) +class TestDefaultValues(BaseTest): + def setUp(self): + self.parser = OptionParser() + self.parser.add_option("-v", "--verbose", default=True) + self.parser.add_option("-q", "--quiet", dest='verbose') + self.parser.add_option("-n", type="int", default=37) + self.parser.add_option("-m", type="int") + self.parser.add_option("-s", default="foo") + self.parser.add_option("-t") + self.parser.add_option("-u", default=None) + + def test_basic_defaults(self): + self.assertEqual(self.parser.get_default_values(), + { 'verbose': True, + 'n': 37, + 'm': None, + 's': "foo", + 't': None, + 'u': None }) + + def test_mixed_defaults_post(self): + self.parser.set_defaults(n=42, m=-100) + self.assertEqual(self.parser.get_default_values(), + { 'verbose': True, + 'n': 42, + 'm': -100, + 's': "foo", + 't': None, + 'u': None }) + + def test_mixed_defaults_pre(self): + self.parser.set_defaults(x="barf", y="blah") + self.parser.add_option("-x", default="frob") + self.parser.add_option("-y") + self.assertEqual(self.parser.get_default_values(), + { 'verbose': True, + 'n': 37, + 'm': None, + 's': "foo", + 'u': None, + 't': None, + 'x': "frob", + 'y': "blah" }) + class TestProgName(BaseTest): """ Test that %prog expands to the right thing in usage, version, @@ -366,7 +410,7 @@ self.assertHelp(parser, expected_usage + "\n") -class TestDefaultValues(BaseTest): +class TestExpandDefaults(BaseTest): def setUp(self): self.parser = OptionParser(prog="test") self.help_prefix = """\ |
From: Greg W. <gw...@us...> - 2004-05-29 02:32:23
|
Update of /cvsroot/optik/optik/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7990 Modified Files: errors.py help.py option.py option_parser.py Log Message: Fix whitespace: change "def foo (...)" to "def foo(...)". Index: errors.py =================================================================== RCS file: /cvsroot/optik/optik/lib/errors.py,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- errors.py 21 Apr 2003 01:53:28 -0000 1.7 +++ errors.py 29 May 2004 02:32:09 -0000 1.8 @@ -15,10 +15,10 @@ class OptikError (Exception): - def __init__ (self, msg): + def __init__(self, msg): self.msg = msg - def __str__ (self): + def __str__(self): return self.msg @@ -28,11 +28,11 @@ inconsistent arguments. """ - def __init__ (self, msg, option): + def __init__(self, msg, option): self.msg = msg self.option_id = str(option) - def __str__ (self): + def __str__(self): if self.option_id: return "option %s: %s" % (self.option_id, self.msg) else: Index: option_parser.py =================================================================== RCS file: /cvsroot/optik/optik/lib/option_parser.py,v retrieving revision 1.58 retrieving revision 1.59 diff -u -d -r1.58 -r1.59 --- option_parser.py 22 May 2004 16:49:56 -0000 1.58 +++ option_parser.py 29 May 2004 02:32:09 -0000 1.59 @@ -26,16 +26,16 @@ class Values: - def __init__ (self, defaults=None): + def __init__(self, defaults=None): if defaults: for (attr, val) in defaults.items(): setattr(self, attr, val) - def __repr__ (self): + def __repr__(self): return ("<%s at 0x%x: %r>" % (self.__class__.__name__, id(self), self.__dict__)) - def _update_careful (self, dict): + def _update_careful(self, dict): """ Update the option values from an arbitrary dictionary, but only use keys from dict that already have a corresponding attribute @@ -48,7 +48,7 @@ if dval is not None: setattr(self, attr, dval) - def _update_loose (self, dict): + def _update_loose(self, dict): """ Update the option values from an arbitrary dictionary, using all keys from the dictionary regardless of whether @@ -56,7 +56,7 @@ """ self.__dict__.update(dict) - def _update (self, dict, mode): + def _update(self, dict, mode): if mode == "careful": self._update_careful(dict) elif mode == "loose": @@ -64,17 +64,17 @@ else: raise ValueError, "invalid update mode: %r" % mode - def read_module (self, modname, mode="careful"): + def read_module(self, modname, mode="careful"): __import__(modname) mod = sys.modules[modname] self._update(vars(mod), mode) - def read_file (self, filename, mode="careful"): + def read_file(self, filename, mode="careful"): vars = {} execfile(filename, vars) self._update(vars, mode) - def ensure_value (self, attr, value): + def ensure_value(self, attr, value): if not hasattr(self, attr) or getattr(self, attr) is None: setattr(self, attr, value) return getattr(self, attr) @@ -112,7 +112,7 @@ """ - def __init__ (self, option_class, conflict_handler, description): + def __init__(self, option_class, conflict_handler, description): # Initialize the option list and related data structures. # This method must be provided by subclasses, and it must # initialize at least the following instance attributes: @@ -123,7 +123,7 @@ self.set_conflict_handler(conflict_handler) self.set_description(description) - def _create_option_mappings (self): + def _create_option_mappings(self): # For use by OptionParser constructor -- create the master # option mappings used by this OptionParser and all # OptionGroups that it owns. @@ -132,25 +132,25 @@ self.defaults = {} # maps option dest -> default value - def _share_option_mappings (self, parser): + def _share_option_mappings(self, parser): # For use by OptionGroup constructor -- use shared option # mappings from the OptionParser that owns this OptionGroup. self._short_opt = parser._short_opt self._long_opt = parser._long_opt self.defaults = parser.defaults - def set_conflict_handler (self, handler): + def set_conflict_handler(self, handler): if handler not in ("ignore", "error", "resolve"): raise ValueError, "invalid conflict_resolution value %r" % handler self.conflict_handler = handler - def set_description (self, description): + def set_description(self, description): self.description = description # -- Option-adding methods ----------------------------------------- - def _check_conflict (self, option): + def _check_conflict(self, option): conflict_opts = [] for opt in option._short_opts: if self._short_opt.has_key(opt): @@ -179,7 +179,7 @@ if not (c_option._short_opts or c_option._long_opts): c_option.container.option_list.remove(c_option) - def add_option (self, *args, **kwargs): + def add_option(self, *args, **kwargs): """add_option(Option) add_option(opt_str, ..., kwarg=val, ...) """ @@ -209,21 +209,21 @@ return option - def add_options (self, option_list): + def add_options(self, option_list): for option in option_list: self.add_option(option) # -- Option query/removal methods ---------------------------------- - def get_option (self, opt_str): + def get_option(self, opt_str): return (self._short_opt.get(opt_str) or self._long_opt.get(opt_str)) - def has_option (self, opt_str): + def has_option(self, opt_str): return (self._short_opt.has_key(opt_str) or self._long_opt.has_key(opt_str)) - def remove_option (self, opt_str): + def remove_option(self, opt_str): option = self._short_opt.get(opt_str) if option is None: option = self._long_opt.get(opt_str) @@ -239,7 +239,7 @@ # -- Help-formatting methods --------------------------------------- - def format_option_help (self, formatter): + def format_option_help(self, formatter): if not self.option_list: return "" result = [] @@ -248,13 +248,13 @@ result.append(formatter.format_option(option)) return "".join(result) - def format_description (self, formatter): + def format_description(self, formatter): if self.description: return formatter.format_description(self.description) else: return "" - def format_help (self, formatter): + def format_help(self, formatter): result = [] if self.description: result.append(self.format_description(formatter)) @@ -265,22 +265,22 @@ class OptionGroup (OptionContainer): - def __init__ (self, parser, title, description=None): + def __init__(self, parser, title, description=None): self.parser = parser OptionContainer.__init__( self, parser.option_class, parser.conflict_handler, description) self.title = title - def _create_option_list (self): + def _create_option_list(self): self.option_list = [] self._share_option_mappings(self.parser) - def set_title (self, title): + def set_title(self, title): self.title = title # -- Help-formatting methods --------------------------------------- - def format_help (self, formatter): + def format_help(self, formatter): result = formatter.format_heading(self.title) formatter.indent() result += OptionContainer.format_help(self, formatter) @@ -340,16 +340,16 @@ standard_option_list = [] - def __init__ (self, - usage=None, - option_list=None, - option_class=Option, - version=None, - conflict_handler="error", - description=None, - formatter=None, - add_help_option=1, - prog=None): + def __init__(self, + usage=None, + option_list=None, + option_class=Option, + version=None, + conflict_handler="error", + description=None, + formatter=None, + add_help_option=1, + prog=None): OptionContainer.__init__( self, option_class, conflict_handler, description) self.set_usage(usage) @@ -373,22 +373,22 @@ # -- Private methods ----------------------------------------------- # (used by our or OptionContainer's constructor) - def _create_option_list (self): + def _create_option_list(self): self.option_list = [] self.option_groups = [] self._create_option_mappings() - def _add_help_option (self): + def _add_help_option(self): self.add_option("-h", "--help", action="help", help="show this help message and exit") - def _add_version_option (self): + def _add_version_option(self): self.add_option("--version", action="version", help="show program's version number and exit") - def _populate_option_list (self, option_list, add_help=1): + def _populate_option_list(self, option_list, add_help=1): if self.standard_option_list: self.add_options(self.standard_option_list) if option_list: @@ -398,7 +398,7 @@ if add_help: self._add_help_option() - def _init_parsing_state (self): + def _init_parsing_state(self): # These are set in parse_args() for the convenience of callbacks. self.rargs = None self.largs = None @@ -407,7 +407,7 @@ # -- Simple modifier methods --------------------------------------- - def set_usage (self, usage): + def set_usage(self, usage): if usage is None: self.usage = "%prog [options]" elif usage is SUPPRESS_USAGE: @@ -418,25 +418,25 @@ else: self.usage = usage - def enable_interspersed_args (self): + def enable_interspersed_args(self): self.allow_interspersed_args = 1 - def disable_interspersed_args (self): + def disable_interspersed_args(self): self.allow_interspersed_args = 0 - def set_default (self, dest, value): + def set_default(self, dest, value): self.defaults[dest] = value - def set_defaults (self, **kwargs): + def set_defaults(self, **kwargs): self.defaults.update(kwargs) - def get_default_values (self): + def get_default_values(self): return Values(self.defaults) # -- OptionGroup methods ------------------------------------------- - def add_option_group (self, *args, **kwargs): + def add_option_group(self, *args, **kwargs): # XXX lots of overlap with OptionContainer.add_option() if type(args[0]) is types.StringType: group = OptionGroup(self, *args, **kwargs) @@ -452,7 +452,7 @@ self.option_groups.append(group) return group - def get_option_group (self, opt_str): + def get_option_group(self, opt_str): option = (self._short_opt.get(opt_str) or self._long_opt.get(opt_str)) if option and option.container is not self: @@ -462,13 +462,13 @@ # -- Option-parsing methods ---------------------------------------- - def _get_args (self, args): + def _get_args(self, args): if args is None: return sys.argv[1:] else: return args[:] # don't modify caller's list - def parse_args (self, args=None, values=None): + def parse_args(self, args=None, values=None): """ parse_args(args : [string] = sys.argv[1:], values : Values = None) @@ -507,7 +507,7 @@ args = largs + rargs return self.check_values(values, args) - def check_values (self, values, args): + def check_values(self, values, args): """ check_values(values : Values, args : [string]) -> (values : Values, args : [string]) @@ -520,7 +520,7 @@ """ return (values, args) - def _process_args (self, largs, rargs, values): + def _process_args(self, largs, rargs, values): """_process_args(largs : [string], rargs : [string], values : Values) @@ -571,7 +571,7 @@ # *empty* -- still a subset of [arg0, ..., arg(i-1)], but # not a very interesting subset! - def _match_long_opt (self, opt): + def _match_long_opt(self, opt): """_match_long_opt(opt : string) -> string Determine which long option string 'opt' matches, ie. which one @@ -580,7 +580,7 @@ """ return _match_abbrev(opt, self._long_opt) - def _process_long_opt (self, rargs, values): + def _process_long_opt(self, rargs, values): arg = rargs.pop(0) # Value explicitly attached to arg? Pretend it's the next @@ -617,7 +617,7 @@ option.process(opt, value, values, self) - def _process_short_opts (self, rargs, values): + def _process_short_opts(self, rargs, values): arg = rargs.pop(0) stop = 0 i = 1 @@ -659,13 +659,13 @@ # -- Feedback methods ---------------------------------------------- - def get_prog_name (self): + def get_prog_name(self): if self.prog is None: return os.path.basename(sys.argv[0]) else: return self.prog - def error (self, msg): + def error(self, msg): """error(msg : string) Print a usage message incorporating 'msg' to stderr and exit. @@ -676,14 +676,14 @@ sys.stderr.write("%s: error: %s\n" % (self.get_prog_name(), msg)) sys.exit(2) # command-line usage error - def get_usage (self): + def get_usage(self): if self.usage: return self.formatter.format_usage( self.usage.replace("%prog", self.get_prog_name())) else: return "" - def print_usage (self, file=None): + def print_usage(self, file=None): """print_usage(file : file = stdout) Print the usage message for the current program (self.usage) to @@ -695,13 +695,13 @@ if self.usage: print >>file, self.get_usage() - def get_version (self): + def get_version(self): if self.version: return self.version.replace("%prog", self.get_prog_name()) else: return "" - def print_version (self, file=None): + def print_version(self, file=None): """print_version(file : file = stdout) Print the version message for this program (self.version) to @@ -712,7 +712,7 @@ if self.version: print >>file, self.get_version() - def format_option_help (self, formatter=None): + def format_option_help(self, formatter=None): if formatter is None: formatter = self.formatter formatter.store_option_strings(self) @@ -729,7 +729,7 @@ # Drop the last "\n", or the header if no options or option groups: return "".join(result[:-1]) - def format_help (self, formatter=None): + def format_help(self, formatter=None): if formatter is None: formatter = self.formatter result = [] @@ -740,7 +740,7 @@ result.append(self.format_option_help(formatter)) return "".join(result) - def print_help (self, file=None): + def print_help(self, file=None): """print_help(file : file = stdout) Print an extended help message, listing all options and any @@ -753,7 +753,7 @@ # class OptionParser -def _match_abbrev (s, wordmap): +def _match_abbrev(s, wordmap): """_match_abbrev(s : string, wordmap : {string : Option}) -> string Return the string key in 'wordmap' for which 's' is an unambiguous Index: help.py =================================================================== RCS file: /cvsroot/optik/optik/lib/help.py,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- help.py 29 May 2004 01:54:24 -0000 1.9 +++ help.py 29 May 2004 02:32:09 -0000 1.10 @@ -50,11 +50,11 @@ NO_DEFAULT_VALUE = "none" - def __init__ (self, - indent_increment, - max_help_position, - width, - short_first): + def __init__(self, + indent_increment, + max_help_position, + width, + short_first): self.parser = None self.indent_increment = indent_increment self.help_position = self.max_help_position = max_help_position @@ -83,22 +83,22 @@ "invalid metavar delimiter for long options: %r" % delim) self._long_opt_fmt = "%s" + delim + "%s" - def indent (self): + def indent(self): self.current_indent += self.indent_increment self.level += 1 - def dedent (self): + def dedent(self): self.current_indent -= self.indent_increment assert self.current_indent >= 0, "Indent decreased below 0." self.level -= 1 - def format_usage (self, usage): + def format_usage(self, usage): raise NotImplementedError, "subclasses must implement" - def format_heading (self, heading): + def format_heading(self, heading): raise NotImplementedError, "subclasses must implement" - def format_description (self, description): + def format_description(self, description): desc_width = self.width - self.current_indent indent = " "*self.current_indent return textwrap.fill(description, desc_width, @@ -115,7 +115,7 @@ return option.help.replace(self.default_tag, str(default_value)) - def format_option (self, option): + def format_option(self, option): # The help for each option consists of two parts: # * the opt strings and metavars # eg. ("-x", or "-fFILENAME, --file=FILENAME") @@ -150,7 +150,7 @@ result.append("\n") return "".join(result) - def store_option_strings (self, parser): + def store_option_strings(self, parser): self.indent() max_len = 0 for opt in parser.option_list: @@ -167,7 +167,7 @@ self.dedent() self.help_position = min(max_len + 2, self.max_help_position) - def format_option_strings (self, option): + def format_option_strings(self, option): """Return a comma-separated list of option strings & metavariables.""" if option.takes_value(): metavar = option.metavar or option.dest.upper() @@ -190,18 +190,18 @@ """Format help with indented section bodies. """ - def __init__ (self, - indent_increment=2, - max_help_position=24, - width=78, - short_first=1): + def __init__(self, + indent_increment=2, + max_help_position=24, + width=78, + short_first=1): HelpFormatter.__init__( self, indent_increment, max_help_position, width, short_first) - def format_usage (self, usage): + def format_usage(self, usage): return "usage: %s\n" % usage - def format_heading (self, heading): + def format_heading(self, heading): return "%*s%s:\n" % (self.current_indent, "", heading) @@ -209,16 +209,16 @@ """Format help with underlined section headers. """ - def __init__ (self, - indent_increment=0, - max_help_position=24, - width=78, - short_first=0): + def __init__(self, + indent_increment=0, + max_help_position=24, + width=78, + short_first=0): HelpFormatter.__init__ ( self, indent_increment, max_help_position, width, short_first) - def format_usage (self, usage): + def format_usage(self, usage): return "%s %s\n" % (self.format_heading("Usage"), usage) - def format_heading (self, heading): + def format_heading(self, heading): return "%s\n%s\n" % (heading, "=-"[self.level] * len(heading)) Index: option.py =================================================================== RCS file: /cvsroot/optik/optik/lib/option.py,v retrieving revision 1.26 retrieving revision 1.27 diff -u -d -r1.26 -r1.27 --- option.py 8 May 2003 01:20:36 -0000 1.26 +++ option.py 29 May 2004 02:32:09 -0000 1.27 @@ -27,7 +27,7 @@ "float" : (float, "floating-point"), "complex" : (complex, "complex") } -def check_builtin (option, opt, value): +def check_builtin(option, opt, value): (cvt, what) = _builtin_cvt[option.type] try: return cvt(value) @@ -154,7 +154,7 @@ # -- Constructor/initialization methods ---------------------------- - def __init__ (self, *opts, **attrs): + def __init__(self, *opts, **attrs): # Set _short_opts, _long_opts attrs from 'opts' tuple. # Have to be set now, in case no option strings are supplied. self._short_opts = [] @@ -173,7 +173,7 @@ for checker in self.CHECK_METHODS: checker(self) - def _check_opt_strings (self, opts): + def _check_opt_strings(self, opts): # Filter out None because early versions of Optik had exactly # one short option and one long option, either of which # could be None. @@ -182,7 +182,7 @@ raise TypeError("at least one option string must be supplied") return opts - def _set_opt_strings (self, opts): + def _set_opt_strings(self, opts): for opt in opts: if len(opt) < 2: raise OptionError( @@ -203,7 +203,7 @@ self) self._long_opts.append(opt) - def _set_attrs (self, attrs): + def _set_attrs(self, attrs): for attr in self.ATTRS: if attrs.has_key(attr): setattr(self, attr, attrs[attr]) @@ -221,13 +221,13 @@ # -- Constructor validation methods -------------------------------- - def _check_action (self): + def _check_action(self): if self.action is None: self.action = "store" elif self.action not in self.ACTIONS: raise OptionError("invalid action: %r" % self.action, self) - def _check_type (self): + def _check_type(self): if self.type is None: # XXX should factor out another class attr here: list of # actions that *require* a type @@ -258,7 +258,7 @@ raise OptionError( "must not supply choices for type %r" % self.type, self) - def _check_dest (self): + def _check_dest(self): if self.action in self.STORE_ACTIONS and self.dest is None: # No destination given, and we need one for this action. # Glean a destination from the first long option string, @@ -269,13 +269,13 @@ else: self.dest = self._short_opts[0][1] - def _check_const (self): + def _check_const(self): if self.action != "store_const" and self.const is not None: raise OptionError( "'const' must not be supplied for action %r" % self.action, self) - def _check_nargs (self): + def _check_nargs(self): if self.action in self.TYPED_ACTIONS: if self.nargs is None: self.nargs = 1 @@ -284,7 +284,7 @@ "'nargs' must not be supplied for action %r" % self.action, self) - def _check_callback (self): + def _check_callback(self): if self.action == "callback": if not callable(self.callback): raise OptionError( @@ -323,23 +323,23 @@ # -- Miscellaneous methods ----------------------------------------- - def __str__ (self): + def __str__(self): return "/".join(self._short_opts + self._long_opts) - def takes_value (self): + def takes_value(self): return self.type is not None # -- Processing methods -------------------------------------------- - def check_value (self, opt, value): + def check_value(self, opt, value): checker = self.TYPE_CHECKER.get(self.type) if checker is None: return value else: return checker(self, opt, value) - def process (self, opt, value, values, parser): + def process(self, opt, value, values, parser): # First, convert the value(s) to the right type. Howl if any # value(s) are bogus. @@ -355,7 +355,7 @@ return self.take_action( self.action, self.dest, opt, value, values, parser) - def take_action (self, action, dest, opt, value, values, parser): + def take_action(self, action, dest, opt, value, values, parser): if action == "store": setattr(values, dest, value) elif action == "store_const": |
From: Greg W. <gw...@us...> - 2004-05-29 02:06:51
|
Update of /cvsroot/optik/optik/examples In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4574/examples Added Files: custom_type.py Log Message: Example code to illustrate the problem described in SF bug #955889. See https://sourceforge.net/tracker/index.php?func=detail&aid=955889&group_id=38019&atid=421097 for details. --- NEW FILE: custom_type.py --- #!/usr/bin/python # Example code that illustrates the problem described in # bug #955889 -- see # https://sourceforge.net/tracker/index.php?func=detail&aid=955889&group_id=38019&atid=421097 # for details. from copy import copy from optik import OptionParser, Option _time_units = { 's' : 1, 'm' : 60, 'h' : 60*60, 'd' : 60*60*24 } def _get_duration(value): if not value[-1].isdigit(): return int(value[:-1]) * _time_units[value[-1]] else: return int(value) def _check_duration(option, opt, value): try: return _get_duration(value) except ValueError, IndexError: raise OptionValueError( 'option %s: invalid duration: %r' % (opt, value)) class MyOption(Option): TYPES = Option.TYPES + ('duration',) TYPE_CHECKER = copy(Option.TYPE_CHECKER) TYPE_CHECKER['duration'] = _check_duration class MyOptionParser(OptionParser): def __init__(self): OptionParser.__init__(self, option_class=MyOption, usage='usage: %prog [options]') self.add_option( '--delay', type='duration', # oops, default doesn't run through type checker #default='5m', default=300, help='self destruct delay [default: %default]') parser = MyOptionParser() (options, args) = parser.parse_args() print 'self destruct in %s seconds' % options.delay |
From: Greg W. <gw...@us...> - 2004-05-29 01:58:53
|
Update of /cvsroot/optik/optik In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3383 Modified Files: README.txt basic.txt Log Message: Change example help text from eg. "-fFILE" to "-f FILE". Index: basic.txt =================================================================== RCS file: /cvsroot/optik/optik/basic.txt,v retrieving revision 1.15 retrieving revision 1.16 diff -u -d -r1.15 -r1.16 --- basic.txt 29 May 2004 01:08:12 -0000 1.15 +++ basic.txt 29 May 2004 01:58:44 -0000 1.16 @@ -249,13 +249,13 @@ usage: <yourscript> [options] arg1 arg2 options: - -h, --help show this help message and exit - -v, --verbose make lots of noise [default] - -q, --quiet be vewwy quiet (I'm hunting wabbits) - -fFILE, --filename=FILE - write output to FILE - -mMODE, --mode=MODE interaction mode: novice, intermediate, or - expert [default: intermediate] + -h, --help show this help message and exit + -v, --verbose make lots of noise [default] + -q, --quiet be vewwy quiet (I'm hunting wabbits) + -f FILE, --filename=FILE + write output to FILE + -m MODE, --mode=MODE interaction mode: novice, intermediate, or + expert [default: intermediate] There's a lot going on here to help Optik generate the best possible help message: @@ -279,7 +279,7 @@ * options that take a value indicate this fact in their automatically-generated help message, e.g. for the "mode" option:: - -mMODE, --mode=MODE + -m MODE, --mode=MODE Here, "MODE" is called the meta-variable: it stands for the argument that the user is expected to supply to ``-m``/``--mode``. By default, @@ -289,7 +289,7 @@ ``metavar="FILE"``, resulting in this automatically-generated option description:: - -fFILE, --filename=FILE + -f FILE, --filename=FILE This is important for more than just saving space, though: the manually written help text uses the meta-variable "FILE", to clue Index: README.txt =================================================================== RCS file: /cvsroot/optik/optik/README.txt,v retrieving revision 1.13 retrieving revision 1.14 diff -u -d -r1.13 -r1.14 --- README.txt 21 Apr 2003 01:50:36 -0000 1.13 +++ README.txt 29 May 2004 01:58:44 -0000 1.14 @@ -41,9 +41,9 @@ usage: <yourscript> [options] options: - -h, --help show this help message and exit - -fFILE, --file=FILE write report to FILE - -q, --quiet don't print status messages to stdout + -h, --help show this help message and exit + -f FILE, --file=FILE write report to FILE + -q, --quiet don't print status messages to stdout That's just a taste of the flexibility Optik gives you in parsing your command-line. See the documentation included in the package for |
From: Greg W. <gw...@us...> - 2004-05-29 01:58:06
|
Update of /cvsroot/optik/optik/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3270 Modified Files: test_optik.py Log Message: Change all expected help strings from the old default style, eg. "-fFILE", to the new style, "-f FILE". Index: test_optik.py =================================================================== RCS file: /cvsroot/optik/optik/test/test_optik.py,v retrieving revision 1.23 retrieving revision 1.24 diff -u -d -r1.23 -r1.24 --- test_optik.py 22 May 2004 16:44:30 -0000 1.23 +++ test_optik.py 29 May 2004 01:57:56 -0000 1.24 @@ -373,13 +373,13 @@ usage: test [options] options: - -h, --help show this help message and exit + -h, --help show this help message and exit """ self.file_help = "read from FILE [default: %default]" self.expected_help_file = self.help_prefix + \ - " -fFILE, --file=FILE read from FILE [default: foo.txt]\n" + " -f FILE, --file=FILE read from FILE [default: foo.txt]\n" self.expected_help_none = self.help_prefix + \ - " -fFILE, --file=FILE read from FILE [default: none]\n" + " -f FILE, --file=FILE read from FILE [default: none]\n" def test_option_default(self): self.parser.add_option("-f", "--file", @@ -422,7 +422,7 @@ help="blow up with probability PROB [default: %default]") self.parser.set_defaults(prob=0.43) expected_help = self.help_prefix + \ - " -pPROB, --prob=PROB blow up with probability PROB [default: 0.43]\n" + " -p PROB, --prob=PROB blow up with probability PROB [default: 0.43]\n" self.assertHelp(self.parser, expected_help) def test_alt_expand(self): @@ -438,7 +438,7 @@ help="read from %default file") self.parser.formatter.default_tag = None expected_help = self.help_prefix + \ - " -fFILE, --file=FILE read from %default file\n" + " -f FILE, --file=FILE read from %default file\n" self.assertHelp(self.parser, expected_help) @@ -1232,11 +1232,11 @@ usage: bar.py [options] options: - -aAPPLE throw APPLEs at basket - -bNUM, --boo=NUM shout "boo!" NUM times (in order to frighten away all - the evil spirits that cause trouble and mayhem) - --foo=FOO store FOO in the foo list for later fooing - -h, --help show this help message and exit + -a APPLE throw APPLEs at basket + -b NUM, --boo=NUM shout "boo!" NUM times (in order to frighten away all + the evil spirits that cause trouble and mayhem) + --foo=FOO store FOO in the foo list for later fooing + -h, --help show this help message and exit """) def test_help_old_usage(self): @@ -1245,11 +1245,11 @@ usage: bar.py [options] options: - -aAPPLE throw APPLEs at basket - -bNUM, --boo=NUM shout "boo!" NUM times (in order to frighten away all - the evil spirits that cause trouble and mayhem) - --foo=FOO store FOO in the foo list for later fooing - -h, --help show this help message and exit + -a APPLE throw APPLEs at basket + -b NUM, --boo=NUM shout "boo!" NUM times (in order to frighten away all + the evil spirits that cause trouble and mayhem) + --foo=FOO store FOO in the foo list for later fooing + -h, --help show this help message and exit """) def test_help_long_opts_first(self): @@ -1258,11 +1258,11 @@ usage: bar.py [options] options: - -aAPPLE throw APPLEs at basket - --boo=NUM, -bNUM shout "boo!" NUM times (in order to frighten away all - the evil spirits that cause trouble and mayhem) - --foo=FOO store FOO in the foo list for later fooing - --help, -h show this help message and exit + -a APPLE throw APPLEs at basket + --boo=NUM, -b NUM shout "boo!" NUM times (in order to frighten away all + the evil spirits that cause trouble and mayhem) + --foo=FOO store FOO in the foo list for later fooing + --help, -h show this help message and exit """) def test_help_title_formatter(self): @@ -1274,11 +1274,11 @@ options ======= --aAPPLE throw APPLEs at basket ---boo=NUM, -bNUM shout "boo!" NUM times (in order to frighten away all - the evil spirits that cause trouble and mayhem) ---foo=FOO store FOO in the foo list for later fooing ---help, -h show this help message and exit +-a APPLE throw APPLEs at basket +--boo=NUM, -b NUM shout "boo!" NUM times (in order to frighten away all + the evil spirits that cause trouble and mayhem) +--foo=FOO store FOO in the foo list for later fooing +--help, -h show this help message and exit """) def test_help_description_groups(self): @@ -1300,17 +1300,17 @@ single options. options: - -aAPPLE throw APPLEs at basket - -bNUM, --boo=NUM shout "boo!" NUM times (in order to frighten away all - the evil spirits that cause trouble and mayhem) - --foo=FOO store FOO in the foo list for later fooing - -h, --help show this help message and exit + -a APPLE throw APPLEs at basket + -b NUM, --boo=NUM shout "boo!" NUM times (in order to frighten away all + the evil spirits that cause trouble and mayhem) + --foo=FOO store FOO in the foo list for later fooing + -h, --help show this help message and exit Dangerous Options: Caution: use of these options is at your own risk. It is believed that some of them bite. - -g Group option. + -g Group option. """) class TestMatchAbbrev(BaseTest): |
From: Greg W. <gw...@us...> - 2004-05-29 01:54:32
|
Update of /cvsroot/optik/optik/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2773 Modified Files: help.py Log Message: SF #815264: make formatting of option strings and metavars more flexible and change the default for short options from eg. "-fFILE" to "-f FILE". Details: * add HelpFormatter instance attributes _{short,long}_opt_fmt * add set_{short,long}_opt_delimter() to set them * modify format_option_strings() to use them Index: help.py =================================================================== RCS file: /cvsroot/optik/optik/lib/help.py,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 --- help.py 22 May 2004 17:11:09 -0000 1.8 +++ help.py 29 May 2004 01:54:24 -0000 1.9 @@ -38,6 +38,14 @@ maps Option instances to the snippet of help text explaining the syntax of that option, e.g. "-h, --help" or "-fFILE, --file=FILE" + _short_opt_fmt : str + format string controlling how short options with values are + printed in help text. Must be either "%s%s" ("-fFILE") or + "%s %s" ("-f FILE"), because those are the two syntaxes that + Optik supports. + _long_opt_fmt : str + similar but for long options; must be either "%s %s" ("--file FILE") + or "%s=%s" ("--file=FILE"). """ NO_DEFAULT_VALUE = "none" @@ -57,10 +65,24 @@ self.short_first = short_first self.default_tag = "%default" self.option_strings = {} + self._short_opt_fmt = "%s %s" + self._long_opt_fmt = "%s=%s" def set_parser(self, parser): self.parser = parser + def set_short_opt_delimiter(self, delim): + if delim not in ("", " "): + raise ValueError( + "invalid metavar delimiter for short options: %r" % delim) + self._short_opt_fmt = "%s" + delim + "%s" + + def set_long_opt_delimiter(self, delim): + if delim not in ("=", " "): + raise ValueError( + "invalid metavar delimiter for long options: %r" % delim) + self._long_opt_fmt = "%s" + delim + "%s" + def indent (self): self.current_indent += self.indent_increment self.level += 1 @@ -149,8 +171,10 @@ """Return a comma-separated list of option strings & metavariables.""" if option.takes_value(): metavar = option.metavar or option.dest.upper() - short_opts = [sopt + metavar for sopt in option._short_opts] - long_opts = [lopt + "=" + metavar for lopt in option._long_opts] + short_opts = [self._short_opt_fmt % (sopt, metavar) + for sopt in option._short_opts] + long_opts = [self._long_opt_fmt % (lopt, metavar) + for lopt in option._long_opts] else: short_opts = option._short_opts long_opts = option._long_opts |
From: Greg W. <gw...@us...> - 2004-05-29 01:08:22
|
Update of /cvsroot/optik/optik In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27857 Modified Files: basic.txt Log Message: Document expansion of default values with "%default". Index: basic.txt =================================================================== RCS file: /cvsroot/optik/optik/basic.txt,v retrieving revision 1.14 retrieving revision 1.15 diff -u -d -r1.14 -r1.15 --- basic.txt 25 May 2004 01:45:56 -0000 1.14 +++ basic.txt 29 May 2004 01:08:12 -0000 1.15 @@ -230,7 +230,7 @@ usage = "usage: %prog [options] arg1 arg2" parser = OptionParser(usage=usage) parser.add_option("-v", "--verbose", - action="store_true", dest="verbose", default=1, + action="store_true", dest="verbose", default=True, help="make lots of noise [default]") parser.add_option("-q", "--quiet", action="store_false", dest="verbose", @@ -239,8 +239,8 @@ metavar="FILE", help="write output to FILE"), parser.add_option("-m", "--mode", default="intermediate", - help="interaction mode: one of 'novice', " - "'intermediate' [default], 'expert'") + help="interaction mode: novice, intermediate, " + "or expert [default: %default]") If Optik encounters either ``"-h"`` or ``"--help"`` on the command-line, or if you just call ``parser.print_help()``, it prints the following to @@ -254,8 +254,8 @@ -q, --quiet be vewwy quiet (I'm hunting wabbits) -fFILE, --filename=FILE write output to FILE - -mMODE, --mode=MODE interaction mode: one of 'novice', 'intermediate' - [default], 'expert' + -mMODE, --mode=MODE interaction mode: novice, intermediate, or + expert [default: intermediate] There's a lot going on here to help Optik generate the best possible help message: @@ -298,9 +298,14 @@ FILE". This is a simple but effective way to make your help text a lot clearer and more useful for end users. +* options that have a default value can include ``%default`` in + the help string -- Optik will replace it with ``str()`` of the + option's default value. If an option has no default value (or the + default value is ``None``), ``%default`` expands to ``none``. -Print a version number ----------------------- + +Printing a version string +------------------------- Similar to the brief usage string, Optik can also print a version string for your program. You have to supply the string, as the ``version`` |
From: Greg W. <gw...@us...> - 2004-05-29 01:05:52
|
Update of /cvsroot/optik/optik In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27312 Modified Files: mkdoc Log Message: Require an output dir -- don't write to the current dir by default. Index: mkdoc =================================================================== RCS file: /cvsroot/optik/optik/mkdoc,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- mkdoc 25 May 2004 00:33:22 -0000 1.2 +++ mkdoc 29 May 2004 01:05:43 -0000 1.3 @@ -8,11 +8,10 @@ from docutils.core import publish_file args = sys.argv[1:] -if args: - outdir = args[0] -else: - outdir = "" +if not args: + sys.exit("usage: mkdoc outdir") +outdir = args[0] for filename in glob("[a-z]*.txt"): outname = os.path.join(outdir, filename.replace(".txt", ".html")) if newer(filename, outname): |
From: David G. <go...@us...> - 2004-05-28 02:21:55
|
Update of /cvsroot/optik/optik In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9307 Modified Files: advanced.txt Log Message: tiny Index: advanced.txt =================================================================== RCS file: /cvsroot/optik/optik/advanced.txt,v retrieving revision 1.21 retrieving revision 1.22 diff -u -d -r1.21 -r1.22 --- advanced.txt 25 May 2004 01:45:56 -0000 1.21 +++ advanced.txt 28 May 2004 02:21:45 -0000 1.22 @@ -53,7 +53,7 @@ * pass it an Option instance (as returned by ``make_option()``) * pass it any combination of positional and keyword arguments that are - acceptable to ``make_option()`` (ie., to the Option constructor), + acceptable to ``make_option()`` (i.e., to the Option constructor), and it will create the Option instance for you (shown above) |
From: Keren E. <yvq...@po...> - 2004-04-07 10:10:01
|
madmen aurae gamic carob cougar musician biscuits statecraft pitied descension forerun hexaglot swietinia kalapooian dulden jakes crudites mood malingerer linguiform salicaceae |
From: Greg W. <gw...@us...> - 2003-09-15 13:40:11
|
Update of /cvsroot/optik/optik In directory sc8-pr-cvs1:/tmp/cvs-serv29794 Modified Files: merge Log Message: Rename handle_cmdline() to parse_args(). Normalize whitespace. Index: merge =================================================================== RCS file: /cvsroot/optik/optik/merge,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- merge 14 Sep 2003 18:28:55 -0000 1.9 +++ merge 15 Sep 2003 13:40:07 -0000 1.10 @@ -1,6 +1,6 @@ #!/usr/bin/python -"""\ +""" Merge the modules in the 'optik' package into one big module, for easy inclusion in other projects (e.g. optparse.py in Python 2.3). """ @@ -16,16 +16,16 @@ from optparse import OptionParser -def open_module (basename): +def open_module(basename): return open(os.path.join("lib", basename + ".py")) -def read_init (): +def read_init(): globals = {} locals = {} execfile("lib/__init__.py", globals, locals) return (locals['__all__'], locals['__version__']) -def handle_cmdline (): +def parse_args(): """ Return command-line options and output destination argument. The options returned are, of course, an optparse.Values instance. @@ -40,9 +40,9 @@ % len(args)) return options, args[0] -def main (): +def main(): # Open the output file and write preamble. - options, outname = handle_cmdline() + options, outname = parse_args() outfile = open(outname, "w") username = pwd.getpwuid(os.getuid())[0] hostname = socket.getfqdn() |
From: David G. <go...@us...> - 2003-09-14 18:28:58
|
Update of /cvsroot/optik/optik In directory sc8-pr-cvs1:/tmp/cvs-serv20742 Modified Files: merge Log Message: added -c/--compatible option to produce an optparse.py compatible with Python 2.0 Index: merge =================================================================== RCS file: /cvsroot/optik/optik/merge,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 --- merge 11 Sep 2003 23:00:57 -0000 1.8 +++ merge 14 Sep 2003 18:28:55 -0000 1.9 @@ -1,9 +1,9 @@ #!/usr/bin/python -# -# Merge the modules in the 'optik' package into one big module, -# for easy inclusion in other projects (eg. Python 2.3). -# +"""\ +Merge the modules in the 'optik' package into one big module, for easy +inclusion in other projects (e.g. optparse.py in Python 2.3). +""" __revision__ = "$Id$" @@ -13,6 +13,7 @@ import socket import time from glob import glob +from optparse import OptionParser def open_module (basename): @@ -24,9 +25,24 @@ execfile("lib/__init__.py", globals, locals) return (locals['__all__'], locals['__version__']) +def handle_cmdline (): + """ + Return command-line options and output destination argument. + The options returned are, of course, an optparse.Values instance. + """ + usage = "usage: %prog [options] destination" + parser = OptionParser(usage=usage, description=__doc__) + parser.add_option("-c", "--compatible", action="store_true", default=0, + help="produce output compatible with Python 2.0") + options, args = parser.parse_args() + if len(args) != 1: + parser.error("incorrect number of arguments (%s, should be 1)" + % len(args)) + return options, args[0] + def main (): # Open the output file and write preamble. - outname = sys.argv[1] + options, outname = handle_cmdline() outfile = open(outname, "w") username = pwd.getpwuid(os.getuid())[0] hostname = socket.getfqdn() @@ -110,6 +126,8 @@ ("help", "class HelpFormatter"), ("option", "_builtin_cvt"), ("option_parser", "SUPPRESS_HELP")] + if options.compatible: + modules[2] = ("option", "# Do the right thing with boolean values") contents = {} revision = {} |
From: David G. <go...@us...> - 2003-09-11 23:01:01
|
Update of /cvsroot/optik/optik In directory sc8-pr-cvs1:/tmp/cvs-serv26738 Modified Files: merge Log Message: fixed regexp (I think -- depends on what the intention was ;-) Index: merge =================================================================== RCS file: /cvsroot/optik/optik/merge,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- merge 7 Sep 2003 17:57:37 -0000 1.7 +++ merge 11 Sep 2003 23:00:57 -0000 1.8 @@ -121,7 +121,7 @@ # Find revision string for this file. for line in contents[name]: - match = re.match(r"^__revision__\s*=\s*\"\$Id$]+) \$\"\s*$", + match = re.match(r"^__revision__\s*=\s*\"\$(Id[^$]+) \$\"\s*$", line) if match: revision[name] = match.group(1) |
From: Greg W. <gw...@us...> - 2003-09-07 18:57:32
|
Update of /cvsroot/optik/optik/examples In directory sc8-pr-cvs1:/tmp/cvs-serv30956/examples Added Files: custom_source.py Log Message: Test/example of parsing args from somewhere other than sys.argv. --- NEW FILE: custom_source.py --- #!/usr/bin/env python # Parsing options from somewhere other than sys.argv with Optik. from optik import Option, OptionParser def main(): # The usual reason for wanting to parse options from somewhere other # than the command-line (sys.argv) is to allow the user (or # sysadmin) to specify default options via a config file, an # environment variable, or some other means. In the real world, # we'd have to worry about finding, reading, and parsing that # external info; for this example, I'll just hard-code an argument # list. # # Also, in the real world you'd probably be content with Optik's # default expansion of %prog (in usage and version strings). For # testing/illustrative purposes, though, I'm also going to supply a # custom value here. prog = "test" usage = "%prog [-a string] [-b int] [--foo string ...]" parser = OptionParser(prog=prog, usage=usage) parser.add_option("-a") parser.add_option("-b", type="int") parser.add_option("--foo", action="append") # First, ask for help -- but intercept Optik's sys.exit() call. try: print "parsing with --help..." parser.parse_args(["--help"]) except SystemExit, err: print "optik called sys.exit(%r)" % err.args else: print "expected optik to exit!" print # Parse a broken command-line and show the error message. try: print "parsing with invalid options..." parser.parse_args(["-b", "xx"]) except SystemExit, err: print "optik called sys.exit(%r)" % err.args else: print "expected an error!" print # Now parse a valid command-line and check the results. print "parsing with valid options..." args = ["-afoo", "-b", "42", "--foo", "hello", "--foo=again"] (options, args) = parser.parse_args(args) assert args == [], "args: expected empty list, got %r" % args assert options.a == "foo", "-a: expected 'foo', got %r" % options.a assert options.b == 42, "-b: expected 42, got %r" % options.b assert options.foo == ["hello", "again"] print "all good!" main() |
From: Greg W. <gw...@us...> - 2003-09-07 18:18:26
|
Update of /cvsroot/optik/optik/test In directory sc8-pr-cvs1:/tmp/cvs-serv23447 Modified Files: test_optik.py Log Message: Spelling: it's "Callback", not "CallBack". Index: test_optik.py =================================================================== RCS file: /cvsroot/optik/optik/test/test_optik.py,v retrieving revision 1.21 retrieving revision 1.22 diff -u -d -r1.21 -r1.22 --- test_optik.py 27 Aug 2003 17:30:53 -0000 1.21 +++ test_optik.py 7 Sep 2003 18:18:19 -0000 1.22 @@ -832,7 +832,7 @@ {'filename': "foo", 'x': 42}, []) -class TestCallBackExtraArgs(BaseTest): +class TestCallbackExtraArgs(BaseTest): def setUp(self): options = [make_option("-p", "--point", action="callback", callback=self.process_tuple, @@ -857,7 +857,7 @@ {'points': [(1,2,3), (4,5,6)]}, []) -class TestCallBackMeddleArgs(BaseTest): +class TestCallbackMeddleArgs(BaseTest): def setUp(self): options = [make_option(str(x), action="callback", callback=self.process_n, dest='things') @@ -886,7 +886,7 @@ {'things': [('foo', '--')]}, [2]) -class TestCallBackManyArgs(BaseTest): +class TestCallbackManyArgs(BaseTest): def setUp(self): options = [make_option("-a", "--apple", action="callback", nargs=2, callback=self.process_many, type="string"), @@ -911,7 +911,7 @@ {}, []) -class TestCallBackCheckAbbrev(BaseTest): +class TestCallbackCheckAbbrev(BaseTest): def setUp(self): self.parser = OptionParser() self.parser.add_option("--foo-bar", action="callback", @@ -923,7 +923,7 @@ def test_abbrev_callback_expansion(self): self.assertParseOK(["--foo"], {}, []) -class TestCallBackVarArgs(BaseTest): +class TestCallbackVarArgs(BaseTest): def setUp(self): options = [make_option("-a", type="int", nargs=2, dest="a"), make_option("-b", action="store_true", dest="b"), |
From: Greg W. <gw...@us...> - 2003-09-07 17:57:43
|
Update of /cvsroot/optik/optik In directory sc8-pr-cvs1:/tmp/cvs-serv19115 Modified Files: merge Log Message: Add a first pass over all input files, so we can parse the __revision__ line and put the Id tag expansions in a comment in the generated file. Fix #! line. Index: merge =================================================================== RCS file: /cvsroot/optik/optik/merge,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- merge 24 Jun 2003 01:13:10 -0000 1.6 +++ merge 7 Sep 2003 17:57:37 -0000 1.7 @@ -1,4 +1,4 @@ -#!/www/python/bin/python +#!/usr/bin/python # # Merge the modules in the 'optik' package into one big module, @@ -8,6 +8,7 @@ __revision__ = "$Id$" import sys, os +import re import pwd import socket import time @@ -68,6 +69,7 @@ print >>outfile, '''\ __copyright__ = """ Copyright (c) 2001-2003 Gregory P. Ward. All rights reserved. +Copyright (c) 2002-2003 Python Software Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -109,10 +111,39 @@ ("option", "_builtin_cvt"), ("option_parser", "SUPPRESS_HELP")] + contents = {} + revision = {} + for (name, s) in modules: infile = open_module(name) + contents[name] = infile.readlines() + infile.close() + + # Find revision string for this file. + for line in contents[name]: + match = re.match(r"^__revision__\s*=\s*\"\$Id$]+) \$\"\s*$", + line) + if match: + revision[name] = match.group(1) + break + else: + sys.exit("error: unable to find/parse __revision__ line " + "from %r module" % name) + + + # Reverse order here to put the most important modules first. Don't + # guard against KeyError: I *want* this script to crash if we can't + # parse the __revision__ line from one of the modules! + print >>outfile, "# This file was generated from:" + modnames = [m for (m, s) in modules] + modnames.reverse() + for name in modnames: + print >>outfile, "# " + revision[name] + print >>outfile + + for (name, s) in modules: copying = 0 - for line in infile: + for line in contents[name]: if line.startswith(s): copying = 1 elif not copying: |
From: David G. <go...@us...> - 2003-08-27 17:30:57
|
Update of /cvsroot/optik/optik/test In directory sc8-pr-cvs1:/tmp/cvs-serv27702 Modified Files: test_optik.py Log Message: updated test suite for recent code changes; passes now Index: test_optik.py =================================================================== RCS file: /cvsroot/optik/optik/test/test_optik.py,v retrieving revision 1.20 retrieving revision 1.21 diff -u -d -r1.20 -r1.21 --- test_optik.py 12 May 2003 01:56:16 -0000 1.20 +++ test_optik.py 27 Aug 2003 17:30:53 -0000 1.21 @@ -121,12 +121,17 @@ def redirected_stdout(self, err): return sys.stdout.getvalue() + def redirected_stderr(self, err): + return sys.stderr.getvalue() + # -- Assertions used in more than one class -------------------- def assertParseFail(self, cmdline_args, expected_output): """Assert the parser fails with the expected message.""" + sys.stderr = StringIO() self.assertRaises(self.parser.parse_args, SystemExit, expected_output, - funcargs=[cmdline_args]) + self.redirected_stderr, funcargs=[cmdline_args]) + sys.stderr = sys.__stderr__ def assertStdoutEquals(self, cmdline_args, expected_output): """Assert the parser prints the expected output on stdout.""" @@ -1212,6 +1217,7 @@ This is the program description. This program has an option group as well as single options. + options: -aAPPLE throw APPLEs at basket -bNUM, --boo=NUM shout "boo!" NUM times (in order to frighten away all @@ -1220,8 +1226,9 @@ -h, --help show this help message and exit Dangerous Options: - Caution: use of these options is at your own risk. It is believed that - some of them bite. + Caution: use of these options is at your own risk. It is believed + that some of them bite. + -g Group option. """) |