mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
Update optparse module and test suite to Optik 1.5a2.
This commit is contained in:
parent
99b5548298
commit
48aa84b24d
2 changed files with 237 additions and 210 deletions
|
@ -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):
|
||||||
|
|
||||||
|
|
||||||
# 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:
|
||||||
"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:
|
||||||
|
|
||||||
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:
|
||||||
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:
|
||||||
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:
|
||||||
|
|
||||||
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):
|
||||||
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):
|
||||||
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
|
||||||
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 ())
|
||||||
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 ())
|
||||||
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 ())
|
||||||
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
|
||||||
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:
|
||||||
sys.stdout = StringIO()
|
try:
|
||||||
self.assertRaises(self.parser.parse_args, (cmdline_args,), None,
|
sys.stdout = StringIO()
|
||||||
SystemExit, expected_output,
|
self.parser.parse_args(cmdline_args)
|
||||||
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()
|
||||||
|
@ -159,120 +177,133 @@ and kwargs %(kwargs)r
|
||||||
|
|
||||||
# -- Test make_option() aka Option -------------------------------------
|
# -- Test make_option() aka Option -------------------------------------
|
||||||
|
|
||||||
# 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(
|
||||||
"of the form -x, (x any non-dash char)",
|
"invalid short option string '--': must be "
|
||||||
["--"])
|
"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(
|
||||||
"must start with --, followed by non-dash",
|
"invalid long option string '---': "
|
||||||
["---"])
|
"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(
|
||||||
["-b"], {'foo': None, 'bar': None})
|
"option -b: invalid keyword arguments: foo, bar",
|
||||||
|
["-b"], {'foo': None, 'bar': None})
|
||||||
|
|
||||||
def test_action_invalid(self):
|
def test_action_invalid(self):
|
||||||
self.assertOptionError("invalid action: 'foo'",
|
self.assertOptionError(
|
||||||
["-b"], {'action': 'foo'})
|
"option -b: invalid action: 'foo'",
|
||||||
|
["-b"], {'action': 'foo'})
|
||||||
|
|
||||||
def test_type_invalid(self):
|
def test_type_invalid(self):
|
||||||
self.assertOptionError("invalid option type: 'foo'",
|
self.assertOptionError(
|
||||||
["-b"], {'type': 'foo'})
|
"option -b: invalid option type: 'foo'",
|
||||||
self.assertOptionError("invalid option type: 'tuple'",
|
["-b"], {'type': 'foo'})
|
||||||
["-b"], {'type': tuple})
|
self.assertOptionError(
|
||||||
|
"option -b: invalid option 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(
|
||||||
["-b"], {'action': 'count', 'type': 'int'})
|
"option -b: must not supply a type for action 'count'",
|
||||||
|
["-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(
|
||||||
"choices for type 'choice'",
|
"option -b/--bad: must supply a list of "
|
||||||
["-b", "--bad"], {'type': "choice"})
|
"choices for 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(
|
||||||
"strings ('%s' supplied)" % typename,
|
"option -b/--bad: choices must be a list of "
|
||||||
["-b", "--bad"],
|
"strings ('%s' supplied)" % typename,
|
||||||
{'type': "choice", 'choices':"bad choices"})
|
["-b", "--bad"],
|
||||||
|
{'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(
|
||||||
["-b"], {'type': 'int', 'choices':"bad"})
|
"option -b: must not supply choices for type 'int'",
|
||||||
|
["-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(
|
||||||
["-b"], {'action': 'callback',
|
"option -b: callback not callable: 'foo'",
|
||||||
'callback': 'foo'})
|
["-b"], {'action': 'callback',
|
||||||
|
'callback': 'foo'})
|
||||||
|
|
||||||
def dummy(self):
|
def dummy(self):
|
||||||
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, "
|
||||||
["-b"], {'action': 'callback',
|
"must be a tuple: not 'foo'",
|
||||||
'callback': self.dummy,
|
["-b"], {'action': 'callback',
|
||||||
'callback_args': 'foo'})
|
'callback': self.dummy,
|
||||||
|
'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, "
|
||||||
["-b"], {'action': 'callback',
|
"must be a dict: not 'foo'",
|
||||||
'callback': self.dummy,
|
["-b"], {'action': 'callback',
|
||||||
'callback_kwargs': 'foo'})
|
'callback': self.dummy,
|
||||||
|
'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'})
|
||||||
|
|
||||||
class TestOptionParser(BaseTest):
|
class TestOptionParser(BaseTest):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -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()
|
||||||
|
@ -346,7 +398,7 @@ class TestTypeAliases(BaseTest):
|
||||||
self.assertEquals(self.parser.get_option("-x").type, "int")
|
self.assertEquals(self.parser.get_option("-x").type, "int")
|
||||||
self.assertEquals(self.parser.get_option("-s").type, "string")
|
self.assertEquals(self.parser.get_option("-s").type, "string")
|
||||||
self.assertEquals(self.parser.get_option("-t").type, "string")
|
self.assertEquals(self.parser.get_option("-t").type, "string")
|
||||||
|
|
||||||
|
|
||||||
# Custom type for testing processing of default values.
|
# Custom type for testing processing of default values.
|
||||||
_time_units = { 's' : 1, 'm' : 60, 'h' : 60*60, 'd' : 60*60*24 }
|
_time_units = { 's' : 1, 'm' : 60, 'h' : 60*60, 'd' : 60*60*24 }
|
||||||
|
@ -434,17 +486,16 @@ 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)
|
||||||
self.assertVersion(parser, "baz.py 1.2")
|
self.assertVersion(parser, "baz.py 1.2")
|
||||||
self.assertHelp(parser,
|
self.assertHelp(parser,
|
||||||
expected_usage + "\n" +
|
expected_usage + "\n" +
|
||||||
"options:\n"
|
"options:\n"
|
||||||
" --version show program's version number and exit\n"
|
" --version show program's version number and exit\n"
|
||||||
" -h, --help show this help message and exit\n")
|
" -h, --help show this help message and exit\n")
|
||||||
finally:
|
finally:
|
||||||
sys.argv[:] = save_argv
|
sys.argv[:] = save_argv
|
||||||
|
|
||||||
|
@ -503,7 +554,7 @@ options:
|
||||||
default=None,
|
default=None,
|
||||||
help=self.file_help)
|
help=self.file_help)
|
||||||
self.assertHelp(self.parser, self.expected_help_none)
|
self.assertHelp(self.parser, self.expected_help_none)
|
||||||
|
|
||||||
def test_default_none_2(self):
|
def test_default_none_2(self):
|
||||||
self.parser.add_option("-f", "--file",
|
self.parser.add_option("-f", "--file",
|
||||||
help=self.file_help)
|
help=self.file_help)
|
||||||
|
@ -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):
|
||||||
|
|
||||||
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):
|
||||||
|
|
||||||
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):
|
||||||
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):
|
||||||
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):
|
||||||
|
|
||||||
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,8 +955,8 @@ 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):
|
||||||
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):
|
||||||
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):
|
||||||
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):
|
||||||
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:
|
||||||
|
|
||||||
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):
|
||||||
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):
|
||||||
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)
|
||||||
|
@ -1441,7 +1463,7 @@ options:
|
||||||
""")
|
""")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class TestMatchAbbrev(BaseTest):
|
class TestMatchAbbrev(BaseTest):
|
||||||
def test_match_abbrev(self):
|
def test_match_abbrev(self):
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue