Commit 48aa84b2 authored by Greg Ward's avatar Greg Ward

Update optparse module and test suite to Optik 1.5a2.

parent 99b55482
...@@ -16,7 +16,7 @@ For support, use the optik-users@lists.sourceforge.net mailing list ...@@ -16,7 +16,7 @@ For support, use the optik-users@lists.sourceforge.net mailing list
# Python developers: please do not make changes to this file, since # Python developers: please do not make changes to this file, since
# it is automatically generated from the Optik source code. # it is automatically generated from the Optik source code.
__version__ = "1.5a1" __version__ = "1.5a2"
__all__ = ['Option', __all__ = ['Option',
'SUPPRESS_HELP', 'SUPPRESS_HELP',
...@@ -76,10 +76,10 @@ def _repr(self): ...@@ -76,10 +76,10 @@ def _repr(self):
# This file was generated from: # This file was generated from:
# Id: option_parser.py,v 1.67 2004/07/24 23:21:21 gward Exp # Id: option_parser.py 421 2004-10-26 00:45:16Z greg
# Id: option.py,v 1.33 2004/07/24 23:21:21 gward Exp # Id: option.py 422 2004-10-26 00:53:47Z greg
# Id: help.py,v 1.15 2004/07/24 23:21:21 gward Exp # Id: help.py 367 2004-07-24 23:21:21Z gward
# Id: errors.py,v 1.9 2004/07/24 23:21:21 gward Exp # Id: errors.py 367 2004-07-24 23:21:21Z gward
class OptParseError (Exception): class OptParseError (Exception):
def __init__(self, msg): def __init__(self, msg):
...@@ -436,11 +436,16 @@ class Option: ...@@ -436,11 +436,16 @@ class Option:
"count") "count")
# The set of actions for which it makes sense to supply a value # The set of actions for which it makes sense to supply a value
# type, ie. where we expect an argument to this option. # type, ie. which may consume an argument from the command line.
TYPED_ACTIONS = ("store", TYPED_ACTIONS = ("store",
"append", "append",
"callback") "callback")
# The set of actions which *require* a value type, ie. that
# always consume an argument from the command line.
ALWAYS_TYPED_ACTIONS = ("store",
"append")
# The set of known types for option parsers. Again, listed here for # The set of known types for option parsers. Again, listed here for
# constructor argument validation. # constructor argument validation.
TYPES = ("string", "int", "long", "float", "complex", "choice") TYPES = ("string", "int", "long", "float", "complex", "choice")
...@@ -557,9 +562,7 @@ class Option: ...@@ -557,9 +562,7 @@ class Option:
def _check_type(self): def _check_type(self):
if self.type is None: if self.type is None:
# XXX should factor out another class attr here: list of if self.action in self.ALWAYS_TYPED_ACTIONS:
# actions that *require* a type
if self.action in ("store", "append"):
if self.choices is not None: if self.choices is not None:
# The "choices" attribute implies "choice" type. # The "choices" attribute implies "choice" type.
self.type = "choice" self.type = "choice"
...@@ -723,10 +726,10 @@ class Option: ...@@ -723,10 +726,10 @@ class Option:
self.callback(self, opt, value, parser, *args, **kwargs) self.callback(self, opt, value, parser, *args, **kwargs)
elif action == "help": elif action == "help":
parser.print_help() parser.print_help()
sys.exit(0) parser.exit()
elif action == "version": elif action == "version":
parser.print_version() parser.print_version()
sys.exit(0) parser.exit()
else: else:
raise RuntimeError, "unknown action %r" % self.action raise RuntimeError, "unknown action %r" % self.action
...@@ -877,7 +880,7 @@ class OptionContainer: ...@@ -877,7 +880,7 @@ class OptionContainer:
self.defaults = parser.defaults self.defaults = parser.defaults
def set_conflict_handler(self, handler): def set_conflict_handler(self, handler):
if handler not in ("ignore", "error", "resolve"): if handler not in ("error", "resolve"):
raise ValueError, "invalid conflict_resolution value %r" % handler raise ValueError, "invalid conflict_resolution value %r" % handler
self.conflict_handler = handler self.conflict_handler = handler
...@@ -901,14 +904,12 @@ class OptionContainer: ...@@ -901,14 +904,12 @@ class OptionContainer:
if conflict_opts: if conflict_opts:
handler = self.conflict_handler handler = self.conflict_handler
if handler == "ignore": # behaviour for Optik 1.0, 1.1 if handler == "error":
pass
elif handler == "error": # new in 1.2
raise OptionConflictError( raise OptionConflictError(
"conflicting option string(s): %s" "conflicting option string(s): %s"
% ", ".join([co[0] for co in conflict_opts]), % ", ".join([co[0] for co in conflict_opts]),
option) option)
elif handler == "resolve": # new in 1.2 elif handler == "resolve":
for (opt, c_option) in conflict_opts: for (opt, c_option) in conflict_opts:
if opt.startswith("--"): if opt.startswith("--"):
c_option._long_opts.remove(opt) c_option._long_opts.remove(opt)
...@@ -1442,6 +1443,11 @@ class OptionParser (OptionContainer): ...@@ -1442,6 +1443,11 @@ class OptionParser (OptionContainer):
def get_description(self): def get_description(self):
return self.expand_prog_name(self.description) return self.expand_prog_name(self.description)
def exit(self, status=0, msg=None):
if msg:
sys.stderr.write(msg)
sys.exit(status)
def error(self, msg): def error(self, msg):
"""error(msg : string) """error(msg : string)
...@@ -1450,8 +1456,7 @@ class OptionParser (OptionContainer): ...@@ -1450,8 +1456,7 @@ class OptionParser (OptionContainer):
should either exit or raise an exception. should either exit or raise an exception.
""" """
self.print_usage(sys.stderr) self.print_usage(sys.stderr)
sys.stderr.write("%s: error: %s\n" % (self.get_prog_name(), msg)) self.exit(2, "%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: if self.usage:
......
...@@ -17,10 +17,37 @@ from cStringIO import StringIO ...@@ -17,10 +17,37 @@ from cStringIO import StringIO
from pprint import pprint from pprint import pprint
from test import test_support from test import test_support
from optparse import (make_option, Option, IndentedHelpFormatter, from optparse import make_option, Option, IndentedHelpFormatter, \
TitledHelpFormatter, OptionParser, OptionContainer, OptionGroup, TitledHelpFormatter, OptionParser, OptionContainer, OptionGroup, \
SUPPRESS_HELP, SUPPRESS_USAGE, OptionError, OptionConflictError, SUPPRESS_HELP, SUPPRESS_USAGE, OptionError, OptionConflictError, \
BadOptionError, OptionValueError, _match_abbrev) BadOptionError, OptionValueError, Values, _match_abbrev
# Do the right thing with boolean values for all known Python versions.
try:
True, False
except NameError:
(True, False) = (1, 0)
class InterceptedError(Exception):
def __init__(self,
error_message=None,
exit_status=None,
exit_message=None):
self.error_message = error_message
self.exit_status = exit_status
self.exit_message = exit_message
def __str__(self):
return self.error_message or self.exit_message or "intercepted error"
class InterceptingOptionParser(OptionParser):
def exit(self, status=0, msg=None):
raise InterceptedError(exit_status=status, exit_message=msg)
def error(self, msg):
raise InterceptedError(error_message=msg)
class BaseTest(unittest.TestCase): class BaseTest(unittest.TestCase):
def assertParseOK(self, args, expected_opts, expected_positional_args): def assertParseOK(self, args, expected_opts, expected_positional_args):
...@@ -58,12 +85,11 @@ Args were %(args)s.""" % locals ()) ...@@ -58,12 +85,11 @@ Args were %(args)s.""" % locals ())
args, args,
kwargs, kwargs,
expected_exception, expected_exception,
expected_output, expected_message):
get_output=None, """
exact_match=False): Assert that the expected exception is raised when calling a
"""Assert the expected exception is raised when calling a function. function, and that the right error message is included with
that exception.
Also check whether the right error message is given for a given error.
Arguments: Arguments:
func -- the function to call func -- the function to call
...@@ -71,9 +97,6 @@ Args were %(args)s.""" % locals ()) ...@@ -71,9 +97,6 @@ Args were %(args)s.""" % locals ())
kwargs -- keyword arguments to `func` kwargs -- keyword arguments to `func`
expected_exception -- exception that should be raised expected_exception -- exception that should be raised
expected_output -- output we expect to see expected_output -- output we expect to see
get_output -- function to call to get the output
exact_match -- whether output must exactly match expected output,
or merely contain it
Returns the exception raised for further testing. Returns the exception raised for further testing.
""" """
...@@ -81,25 +104,18 @@ Args were %(args)s.""" % locals ()) ...@@ -81,25 +104,18 @@ Args were %(args)s.""" % locals ())
args = () args = ()
if kwargs is None: if kwargs is None:
kwargs = {} kwargs = {}
if get_output is None:
get_output = self.exception
try: try:
out = func(*args, **kwargs) func(*args, **kwargs)
except expected_exception, err: except expected_exception, err:
actual_output = get_output(err) actual_message = str(err)
self.assertEqual(actual_message,
if exact_match: expected_message,
match = actual_output == expected_exception """\
else: expected exception message:
match = actual_output.find(expected_output) != -1 '''%(expected_message)s'''
actual exception message:
self.assert_(match, '''%(actual_message)s'''
"""mismatched output
expected output:
'''%(expected_output)s'''
actual output:
'''%(actual_output)s'''
""" % locals()) """ % locals())
return err return err
...@@ -110,44 +126,46 @@ with args %(args)r ...@@ -110,44 +126,46 @@ with args %(args)r
and kwargs %(kwargs)r and kwargs %(kwargs)r
""" % locals ()) """ % locals ())
# -- Functions to be used as the get_output argument to assertRaises ------
def exception(self, err):
return str(err)
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 -------------------- # -- Assertions used in more than one class --------------------
def assertParseFail(self, cmdline_args, expected_output): def assertParseFail(self, cmdline_args, expected_output):
"""Assert the parser fails with the expected message.""" """
save_stderr = sys.stderr Assert the parser fails with the expected message. Caller
must ensure that self.parser is an InterceptingOptionParser.
"""
try: try:
sys.stderr = StringIO() self.parser.parse_args(cmdline_args)
self.assertRaises(self.parser.parse_args, (cmdline_args,), None, except InterceptedError, err:
SystemExit, expected_output, self.assertEqual(err.error_message, expected_output)
self.redirected_stderr) else:
finally: self.assertFalse("expected parse failure")
sys.stderr = save_stderr
def assertStdoutEquals(self, cmdline_args, expected_output): def assertOutput(self,
cmdline_args,
expected_output,
expected_status=0,
expected_error=None):
"""Assert the parser prints the expected output on stdout.""" """Assert the parser prints the expected output on stdout."""
save_stdout = sys.stdout save_stdout = sys.stdout
try:
try: try:
sys.stdout = StringIO() sys.stdout = StringIO()
self.assertRaises(self.parser.parse_args, (cmdline_args,), None, self.parser.parse_args(cmdline_args)
SystemExit, expected_output,
self.redirected_stdout)
finally: finally:
output = sys.stdout.getvalue()
sys.stdout = save_stdout sys.stdout = save_stdout
def assertTypeError(self, func, expected_output, *args): except InterceptedError, err:
"""Assert a TypeError is raised when executing func.""" self.assertEqual(output, expected_output)
self.assertRaises(func, args, None, TypeError, expected_output) self.assertEqual(err.exit_status, expected_status)
self.assertEqual(err.exit_message, expected_error)
else:
self.assertFalse("expected parser.exit()")
def assertTypeError(self, func, expected_message, *args):
"""Assert that TypeError is raised when executing func."""
self.assertRaises(func, args, None, TypeError, expected_message)
def assertHelp(self, parser, expected_help): def assertHelp(self, parser, expected_help):
actual_help = parser.format_help() actual_help = parser.format_help()
...@@ -161,81 +179,92 @@ and kwargs %(kwargs)r ...@@ -161,81 +179,92 @@ and kwargs %(kwargs)r
# It's not necessary to test correct options here. All the tests in the # It's not necessary to test correct options here. All the tests in the
# parser.parse_args() section deal with those, because they're needed # parser.parse_args() section deal with those, because they're needed
# there. Duplication makes no sense to me. # there.
class TestOptionChecks(BaseTest): class TestOptionChecks(BaseTest):
def setUp(self): def setUp(self):
self.parser = OptionParser(usage=SUPPRESS_USAGE) self.parser = OptionParser(usage=SUPPRESS_USAGE)
def assertOptionError(self, expected_output, args=[], kwargs={}): def assertOptionError(self, expected_message, args=[], kwargs={}):
self.assertRaises(make_option, args, kwargs, self.assertRaises(make_option, args, kwargs,
OptionError, expected_output) OptionError, expected_message)
def test_opt_string_empty(self): def test_opt_string_empty(self):
self.assertTypeError(make_option, self.assertTypeError(make_option,
"at least one option string must be supplied") "at least one option string must be supplied")
def test_opt_string_too_short(self): def test_opt_string_too_short(self):
self.assertOptionError("invalid option string 'b': " self.assertOptionError(
"must be at least two characters long", "invalid option string 'b': must be at least two characters long",
["b"]) ["b"])
def test_opt_string_short_invalid(self): def test_opt_string_short_invalid(self):
self.assertOptionError("invalid short option string '--': must be " self.assertOptionError(
"invalid short option string '--': must be "
"of the form -x, (x any non-dash char)", "of the form -x, (x any non-dash char)",
["--"]) ["--"])
def test_opt_string_long_invalid(self): def test_opt_string_long_invalid(self):
self.assertOptionError("invalid long option string '---': " self.assertOptionError(
"invalid long option string '---': "
"must start with --, followed by non-dash", "must start with --, followed by non-dash",
["---"]) ["---"])
def test_attr_invalid(self): def test_attr_invalid(self):
self.assertOptionError("invalid keyword arguments: foo, bar", self.assertOptionError(
"option -b: invalid keyword arguments: foo, bar",
["-b"], {'foo': None, 'bar': None}) ["-b"], {'foo': None, 'bar': None})
def test_action_invalid(self): def test_action_invalid(self):
self.assertOptionError("invalid action: 'foo'", self.assertOptionError(
"option -b: invalid action: 'foo'",
["-b"], {'action': 'foo'}) ["-b"], {'action': 'foo'})
def test_type_invalid(self): def test_type_invalid(self):
self.assertOptionError("invalid option type: 'foo'", self.assertOptionError(
"option -b: invalid option type: 'foo'",
["-b"], {'type': 'foo'}) ["-b"], {'type': 'foo'})
self.assertOptionError("invalid option type: 'tuple'", self.assertOptionError(
"option -b: invalid option type: 'tuple'",
["-b"], {'type': tuple}) ["-b"], {'type': tuple})
def test_no_type_for_action(self): def test_no_type_for_action(self):
self.assertOptionError("must not supply a type for action 'count'", self.assertOptionError(
"option -b: must not supply a type for action 'count'",
["-b"], {'action': 'count', 'type': 'int'}) ["-b"], {'action': 'count', 'type': 'int'})
def test_no_choices_list(self): def test_no_choices_list(self):
self.assertOptionError("must supply a list of " self.assertOptionError(
"option -b/--bad: must supply a list of "
"choices for type 'choice'", "choices for type 'choice'",
["-b", "--bad"], {'type': "choice"}) ["-b", "--bad"], {'type': "choice"})
def test_bad_choices_list(self): def test_bad_choices_list(self):
typename = type('').__name__ typename = type('').__name__
self.assertOptionError("choices must be a list of " self.assertOptionError(
"option -b/--bad: choices must be a list of "
"strings ('%s' supplied)" % typename, "strings ('%s' supplied)" % typename,
["-b", "--bad"], ["-b", "--bad"],
{'type': "choice", 'choices':"bad choices"}) {'type': "choice", 'choices':"bad choices"})
def test_no_choices_for_type(self): def test_no_choices_for_type(self):
self.assertOptionError("must not supply choices for type 'int'", self.assertOptionError(
"option -b: must not supply choices for type 'int'",
["-b"], {'type': 'int', 'choices':"bad"}) ["-b"], {'type': 'int', 'choices':"bad"})
def test_no_const_for_action(self): def test_no_const_for_action(self):
self.assertOptionError("'const' must not be supplied for action " self.assertOptionError(
"'store'", "option -b: 'const' must not be supplied for action 'store'",
["-b"], {'action': 'store', 'const': 1}) ["-b"], {'action': 'store', 'const': 1})
def test_no_nargs_for_action(self): def test_no_nargs_for_action(self):
self.assertOptionError("'nargs' must not be supplied for action " self.assertOptionError(
"'count'", "option -b: 'nargs' must not be supplied for action 'count'",
["-b"], {'action': 'count', 'nargs': 2}) ["-b"], {'action': 'count', 'nargs': 2})
def test_callback_not_callable(self): def test_callback_not_callable(self):
self.assertOptionError("callback not callable: 'foo'", self.assertOptionError(
"option -b: callback not callable: 'foo'",
["-b"], {'action': 'callback', ["-b"], {'action': 'callback',
'callback': 'foo'}) 'callback': 'foo'})
...@@ -243,34 +272,36 @@ class TestOptionChecks(BaseTest): ...@@ -243,34 +272,36 @@ class TestOptionChecks(BaseTest):
pass pass
def test_callback_args_no_tuple(self): def test_callback_args_no_tuple(self):
self.assertOptionError("callback_args, if supplied, must be a tuple: " self.assertOptionError(
"not 'foo'", "option -b: callback_args, if supplied, "
"must be a tuple: not 'foo'",
["-b"], {'action': 'callback', ["-b"], {'action': 'callback',
'callback': self.dummy, 'callback': self.dummy,
'callback_args': 'foo'}) 'callback_args': 'foo'})
def test_callback_kwargs_no_dict(self): def test_callback_kwargs_no_dict(self):
self.assertOptionError("callback_kwargs, if supplied, must be a dict: " self.assertOptionError(
"not 'foo'", "option -b: callback_kwargs, if supplied, "
"must be a dict: not 'foo'",
["-b"], {'action': 'callback', ["-b"], {'action': 'callback',
'callback': self.dummy, 'callback': self.dummy,
'callback_kwargs': 'foo'}) 'callback_kwargs': 'foo'})
def test_no_callback_for_action(self): def test_no_callback_for_action(self):
self.assertOptionError("callback supplied ('foo') for " self.assertOptionError(
"non-callback option", "option -b: callback supplied ('foo') for non-callback option",
["-b"], {'action': 'store', ["-b"], {'action': 'store',
'callback': 'foo'}) 'callback': 'foo'})
def test_no_callback_args_for_action(self): def test_no_callback_args_for_action(self):
self.assertOptionError("callback_args supplied for non-callback " self.assertOptionError(
"option", "option -b: callback_args supplied for non-callback option",
["-b"], {'action': 'store', ["-b"], {'action': 'store',
'callback_args': 'foo'}) 'callback_args': 'foo'})
def test_no_callback_kwargs_for_action(self): def test_no_callback_kwargs_for_action(self):
self.assertOptionError("callback_kwargs supplied for non-callback " self.assertOptionError(
"option", "option -b: callback_kwargs supplied for non-callback option",
["-b"], {'action': 'store', ["-b"], {'action': 'store',
'callback_kwargs': 'foo'}) 'callback_kwargs': 'foo'})
...@@ -335,6 +366,27 @@ class TestOptionParser(BaseTest): ...@@ -335,6 +366,27 @@ class TestOptionParser(BaseTest):
self.assertRaises(self.parser.remove_option, ('foo',), None, self.assertRaises(self.parser.remove_option, ('foo',), None,
ValueError, "no such option 'foo'") ValueError, "no such option 'foo'")
class TestOptionValues(BaseTest):
def setUp(self):
pass
def test_basics(self):
values = Values()
self.assertEqual(vars(values), {})
self.assertEqual(values, {})
self.assertNotEqual(values, {"foo": "bar"})
self.assertNotEqual(values, "")
dict = {"foo": "bar", "baz": 42}
values = Values(defaults=dict)
self.assertEqual(vars(values), dict)
self.assertEqual(values, dict)
self.assertNotEqual(values, {"foo": "bar"})
self.assertNotEqual(values, {})
self.assertNotEqual(values, "")
self.assertNotEqual(values, [])
class TestTypeAliases(BaseTest): class TestTypeAliases(BaseTest):
def setUp(self): def setUp(self):
self.parser = OptionParser() self.parser = OptionParser()
...@@ -434,8 +486,7 @@ class TestProgName(BaseTest): ...@@ -434,8 +486,7 @@ class TestProgName(BaseTest):
# Make sure that program name taken from sys.argv[0] by default. # Make sure that program name taken from sys.argv[0] by default.
save_argv = sys.argv[:] save_argv = sys.argv[:]
try: try:
# XXX Should the path be hard-coding forward-slashes? sys.argv[0] = os.path.join("foo", "bar", "baz.py")
sys.argv[0] = "/foo/bar/baz.py"
parser = OptionParser("usage: %prog ...", version="%prog 1.2") parser = OptionParser("usage: %prog ...", version="%prog 1.2")
expected_usage = "usage: baz.py ...\n" expected_usage = "usage: baz.py ...\n"
self.assertUsage(parser, expected_usage) self.assertUsage(parser, expected_usage)
...@@ -544,7 +595,8 @@ class TestStandard(BaseTest): ...@@ -544,7 +595,8 @@ class TestStandard(BaseTest):
make_option("-b", "--boo", type="int", dest='boo'), make_option("-b", "--boo", type="int", dest='boo'),
make_option("--foo", action="append")] make_option("--foo", action="append")]
self.parser = OptionParser(usage=SUPPRESS_USAGE, option_list=options) self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE,
option_list=options)
def test_required_value(self): def test_required_value(self):
self.assertParseFail(["-a"], "-a option requires an argument") self.assertParseFail(["-a"], "-a option requires an argument")
...@@ -707,7 +759,7 @@ class TestBool(BaseTest): ...@@ -707,7 +759,7 @@ class TestBool(BaseTest):
class TestChoice(BaseTest): class TestChoice(BaseTest):
def setUp(self): def setUp(self):
self.parser = OptionParser(usage=SUPPRESS_USAGE) self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE)
self.parser.add_option("-c", action="store", type="choice", self.parser.add_option("-c", action="store", type="choice",
dest="choice", choices=["one", "two", "three"]) dest="choice", choices=["one", "two", "three"])
...@@ -730,7 +782,7 @@ class TestChoice(BaseTest): ...@@ -730,7 +782,7 @@ class TestChoice(BaseTest):
class TestCount(BaseTest): class TestCount(BaseTest):
def setUp(self): def setUp(self):
self.parser = OptionParser(usage=SUPPRESS_USAGE) self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE)
self.v_opt = make_option("-v", action="count", dest="verbose") self.v_opt = make_option("-v", action="count", dest="verbose")
self.parser.add_option(self.v_opt) self.parser.add_option(self.v_opt)
self.parser.add_option("--verbose", type="int", dest="verbose") self.parser.add_option("--verbose", type="int", dest="verbose")
...@@ -786,9 +838,9 @@ class TestCount(BaseTest): ...@@ -786,9 +838,9 @@ class TestCount(BaseTest):
self.assertParseOK(["-vvv", "--verbose=2", "-q", "-v"], self.assertParseOK(["-vvv", "--verbose=2", "-q", "-v"],
{'verbose': 1}, []) {'verbose': 1}, [])
class TestNArgs(BaseTest): class TestMultipleArgs(BaseTest):
def setUp(self): def setUp(self):
self.parser = OptionParser(usage=SUPPRESS_USAGE) self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE)
self.parser.add_option("-p", "--point", self.parser.add_option("-p", "--point",
action="store", nargs=3, type="float", dest="point") action="store", nargs=3, type="float", dest="point")
...@@ -811,9 +863,9 @@ class TestNArgs(BaseTest): ...@@ -811,9 +863,9 @@ class TestNArgs(BaseTest):
self.assertParseFail(["--point", "1.0", "3.5"], self.assertParseFail(["--point", "1.0", "3.5"],
"--point option requires 3 arguments") "--point option requires 3 arguments")
class TestNArgsAppend(BaseTest): class TestMultipleArgsAppend(BaseTest):
def setUp(self): def setUp(self):
self.parser = OptionParser(usage=SUPPRESS_USAGE) self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE)
self.parser.add_option("-p", "--point", action="store", nargs=3, self.parser.add_option("-p", "--point", action="store", nargs=3,
type="float", dest="point") type="float", dest="point")
self.parser.add_option("-f", "--foo", action="append", nargs=2, self.parser.add_option("-f", "--foo", action="append", nargs=2,
...@@ -835,14 +887,17 @@ class TestNArgsAppend(BaseTest): ...@@ -835,14 +887,17 @@ class TestNArgsAppend(BaseTest):
class TestVersion(BaseTest): class TestVersion(BaseTest):
def test_version(self): def test_version(self):
oldargv = sys.argv[0] self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE,
sys.argv[0] = "./foo/bar" version="%prog 0.1")
self.parser = OptionParser(usage=SUPPRESS_USAGE, version="%prog 0.1") save_argv = sys.argv[:]
self.assertStdoutEquals(["--version"], "bar 0.1\n") try:
sys.argv[0] = oldargv sys.argv[0] = os.path.join(os.curdir, "foo", "bar")
self.assertOutput(["--version"], "bar 0.1\n")
finally:
sys.argv[:] = save_argv
def test_no_version(self): def test_no_version(self):
self.parser = OptionParser(usage=SUPPRESS_USAGE) self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE)
self.assertParseFail(["--version"], self.assertParseFail(["--version"],
"no such option: --version") "no such option: --version")
...@@ -900,7 +955,7 @@ class TestOptionGroup(BaseTest): ...@@ -900,7 +955,7 @@ class TestOptionGroup(BaseTest):
class TestExtendAddTypes(BaseTest): class TestExtendAddTypes(BaseTest):
def setUp(self): def setUp(self):
self.parser = OptionParser(usage=SUPPRESS_USAGE, self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE,
option_class=self.MyOption) option_class=self.MyOption)
self.parser.add_option("-a", None, type="string", dest="a") self.parser.add_option("-a", None, type="string", dest="a")
self.parser.add_option("-f", "--file", type="file", dest="file") self.parser.add_option("-f", "--file", type="file", dest="file")
...@@ -1119,7 +1174,8 @@ class TestCallbackVarArgs(BaseTest): ...@@ -1119,7 +1174,8 @@ class TestCallbackVarArgs(BaseTest):
make_option("-b", action="store_true", dest="b"), make_option("-b", action="store_true", dest="b"),
make_option("-c", "--callback", action="callback", make_option("-c", "--callback", action="callback",
callback=self.variable_args, dest="c")] callback=self.variable_args, dest="c")]
self.parser = OptionParser(usage=SUPPRESS_USAGE, option_list=options) self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE,
option_list=options)
def variable_args (self, option, opt, value, parser): def variable_args (self, option, opt, value, parser):
self.assert_(value is None) self.assert_(value is None)
...@@ -1170,7 +1226,8 @@ class ConflictBase(BaseTest): ...@@ -1170,7 +1226,8 @@ class ConflictBase(BaseTest):
def setUp(self): def setUp(self):
options = [make_option("-v", "--verbose", action="count", options = [make_option("-v", "--verbose", action="count",
dest="verbose", help="increment verbosity")] dest="verbose", help="increment verbosity")]
self.parser = OptionParser(usage=SUPPRESS_USAGE, option_list=options) self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE,
option_list=options)
def show_version (self, option, opt, value, parser): def show_version (self, option, opt, value, parser):
parser.values.show_version = 1 parser.values.show_version = 1
...@@ -1201,41 +1258,6 @@ class TestConflict(ConflictBase): ...@@ -1201,41 +1258,6 @@ class TestConflict(ConflictBase):
ValueError, "invalid conflict_resolution value 'foo'") ValueError, "invalid conflict_resolution value 'foo'")
class TestConflictIgnore(ConflictBase):
"""Test the old (Optik <= 1.1 behaviour) -- arguably broken, but
still available so should be tested.
"""
def setUp(self):
ConflictBase.setUp(self)
self.parser.set_conflict_handler("ignore")
self.parser.add_option("-v", "--version", action="callback",
callback=self.show_version, help="show version")
def test_conflict_ignore(self):
v_opt = self.parser.get_option("-v")
verbose_opt = self.parser.get_option("--verbose")
version_opt = self.parser.get_option("--version")
self.assert_(v_opt is version_opt)
self.assert_(v_opt is not verbose_opt)
self.assertEqual(v_opt._long_opts, ["--version"])
self.assertEqual(version_opt._short_opts, ["-v"])
self.assertEqual(verbose_opt._short_opts, ["-v"])
def test_conflict_ignore_help(self):
self.assertStdoutEquals(["-h"], """\
options:
-v, --verbose increment verbosity
-h, --help show this help message and exit
-v, --version show version
""")
def test_conflict_ignore_short_opt(self):
self.assertParseOK(["-v"],
{'show_version': 1, 'verbose': None},
[])
class TestConflictResolve(ConflictBase): class TestConflictResolve(ConflictBase):
def setUp(self): def setUp(self):
ConflictBase.setUp(self) ConflictBase.setUp(self)
...@@ -1257,7 +1279,7 @@ class TestConflictResolve(ConflictBase): ...@@ -1257,7 +1279,7 @@ class TestConflictResolve(ConflictBase):
self.assertEqual(verbose_opt._long_opts, ["--verbose"]) self.assertEqual(verbose_opt._long_opts, ["--verbose"])
def test_conflict_resolve_help(self): def test_conflict_resolve_help(self):
self.assertStdoutEquals(["-h"], """\ self.assertOutput(["-h"], """\
options: options:
--verbose increment verbosity --verbose increment verbosity
-h, --help show this help message and exit -h, --help show this help message and exit
...@@ -1281,7 +1303,7 @@ options: ...@@ -1281,7 +1303,7 @@ options:
class TestConflictOverride(BaseTest): class TestConflictOverride(BaseTest):
def setUp(self): def setUp(self):
self.parser = OptionParser(usage=SUPPRESS_USAGE) self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE)
self.parser.set_conflict_handler("resolve") self.parser.set_conflict_handler("resolve")
self.parser.add_option("-n", "--dry-run", self.parser.add_option("-n", "--dry-run",
action="store_true", dest="dry_run", action="store_true", dest="dry_run",
...@@ -1296,7 +1318,7 @@ class TestConflictOverride(BaseTest): ...@@ -1296,7 +1318,7 @@ class TestConflictOverride(BaseTest):
self.assertEqual(opt._long_opts, ["--dry-run"]) self.assertEqual(opt._long_opts, ["--dry-run"])
def test_conflict_override_help(self): def test_conflict_override_help(self):
self.assertStdoutEquals(["-h"], """\ self.assertOutput(["-h"], """\
options: options:
-h, --help show this help message and exit -h, --help show this help message and exit
-n, --dry-run dry run mode -n, --dry-run dry run mode
...@@ -1375,16 +1397,16 @@ class TestHelp(BaseTest): ...@@ -1375,16 +1397,16 @@ class TestHelp(BaseTest):
help="store FOO in the foo list for later fooing"), help="store FOO in the foo list for later fooing"),
] ]
os.environ['COLUMNS'] = str(columns) os.environ['COLUMNS'] = str(columns)
return OptionParser(option_list=options) return InterceptingOptionParser(option_list=options)
def assertHelpEquals(self, expected_output): def assertHelpEquals(self, expected_output):
# This trick is used to make optparse believe bar.py is being executed. save_argv = sys.argv[:]
oldargv = sys.argv[0] try:
sys.argv[0] = "./foo/bar.py" # Make optparse believe bar.py is being executed.
sys.argv[0] = os.path.join("foo", "bar.py")
self.assertStdoutEquals(["-h"], expected_output) self.assertOutput(["-h"], expected_output)
finally:
sys.argv[0] = oldargv sys.argv[:] = save_argv
def test_help(self): def test_help(self):
self.assertHelpEquals(_expected_help_basic) self.assertHelpEquals(_expected_help_basic)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment