blob: dc2ef0b7867516982e7fe9b7d3d8ae76706208bb [file] [log] [blame]
Greg Ward55493222003-04-21 02:41:25 +00001#
2# Test suite for Optik. Supplied by Johannes Gijsbers
3# (taradino@softhome.net) -- translated from the original Optik
4# test suite to this PyUnit-based version.
5#
6# $Id$
7#
8
9import sys
10import os
Greg Wardab05edc2006-04-23 03:47:58 +000011import re
Greg Ward55493222003-04-21 02:41:25 +000012import copy
Greg Wardab05edc2006-04-23 03:47:58 +000013import types
Greg Ward55493222003-04-21 02:41:25 +000014import unittest
15
Greg Ward0e0c9f42006-06-11 16:24:11 +000016from StringIO import StringIO
Greg Ward55493222003-04-21 02:41:25 +000017from test import test_support
18
Greg Wardab05edc2006-04-23 03:47:58 +000019
Georg Brandla4f46e12010-02-07 17:03:15 +000020from optparse import make_option, Option, \
21 TitledHelpFormatter, OptionParser, OptionGroup, \
22 SUPPRESS_USAGE, OptionError, OptionConflictError, \
Greg Wardab05edc2006-04-23 03:47:58 +000023 BadOptionError, OptionValueError, Values
24from optparse import _match_abbrev
25from optparse import _parse_num
Greg Ward48aa84b2004-10-27 02:20:04 +000026
Greg Wardab05edc2006-04-23 03:47:58 +000027retype = type(re.compile(''))
Greg Ward48aa84b2004-10-27 02:20:04 +000028
29class InterceptedError(Exception):
30 def __init__(self,
31 error_message=None,
32 exit_status=None,
33 exit_message=None):
34 self.error_message = error_message
35 self.exit_status = exit_status
36 self.exit_message = exit_message
37
38 def __str__(self):
39 return self.error_message or self.exit_message or "intercepted error"
40
41class InterceptingOptionParser(OptionParser):
42 def exit(self, status=0, msg=None):
43 raise InterceptedError(exit_status=status, exit_message=msg)
44
45 def error(self, msg):
46 raise InterceptedError(error_message=msg)
47
Greg Ward55493222003-04-21 02:41:25 +000048
49class BaseTest(unittest.TestCase):
50 def assertParseOK(self, args, expected_opts, expected_positional_args):
51 """Assert the options are what we expected when parsing arguments.
52
53 Otherwise, fail with a nicely formatted message.
54
55 Keyword arguments:
56 args -- A list of arguments to parse with OptionParser.
57 expected_opts -- The options expected.
58 expected_positional_args -- The positional arguments expected.
59
60 Returns the options and positional args for further testing.
61 """
62
63 (options, positional_args) = self.parser.parse_args(args)
64 optdict = vars(options)
65
66 self.assertEqual(optdict, expected_opts,
67 """
68Options are %(optdict)s.
69Should be %(expected_opts)s.
70Args were %(args)s.""" % locals())
71
72 self.assertEqual(positional_args, expected_positional_args,
73 """
74Positional arguments are %(positional_args)s.
75Should be %(expected_positional_args)s.
76Args were %(args)s.""" % locals ())
77
78 return (options, positional_args)
79
Greg Wardeba20e62004-07-31 16:15:44 +000080 def assertRaises(self,
81 func,
82 args,
83 kwargs,
84 expected_exception,
Greg Ward48aa84b2004-10-27 02:20:04 +000085 expected_message):
86 """
87 Assert that the expected exception is raised when calling a
88 function, and that the right error message is included with
89 that exception.
Greg Ward55493222003-04-21 02:41:25 +000090
Greg Wardeba20e62004-07-31 16:15:44 +000091 Arguments:
92 func -- the function to call
93 args -- positional arguments to `func`
94 kwargs -- keyword arguments to `func`
95 expected_exception -- exception that should be raised
Greg Wardab05edc2006-04-23 03:47:58 +000096 expected_message -- expected exception message (or pattern
97 if a compiled regex object)
Greg Ward55493222003-04-21 02:41:25 +000098
99 Returns the exception raised for further testing.
100 """
Greg Wardeba20e62004-07-31 16:15:44 +0000101 if args is None:
102 args = ()
103 if kwargs is None:
104 kwargs = {}
Greg Ward55493222003-04-21 02:41:25 +0000105
106 try:
Greg Ward48aa84b2004-10-27 02:20:04 +0000107 func(*args, **kwargs)
Greg Ward55493222003-04-21 02:41:25 +0000108 except expected_exception, err:
Greg Ward48aa84b2004-10-27 02:20:04 +0000109 actual_message = str(err)
Greg Wardab05edc2006-04-23 03:47:58 +0000110 if isinstance(expected_message, retype):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000111 self.assertTrue(expected_message.search(actual_message),
Greg Ward48aa84b2004-10-27 02:20:04 +0000112 """\
Greg Wardab05edc2006-04-23 03:47:58 +0000113expected exception message pattern:
114/%s/
Greg Ward48aa84b2004-10-27 02:20:04 +0000115actual exception message:
Greg Wardab05edc2006-04-23 03:47:58 +0000116'''%s'''
117""" % (expected_message.pattern, actual_message))
118 else:
119 self.assertEqual(actual_message,
120 expected_message,
121 """\
122expected exception message:
123'''%s'''
124actual exception message:
125'''%s'''
126""" % (expected_message, actual_message))
Greg Ward55493222003-04-21 02:41:25 +0000127
128 return err
129 else:
Greg Wardeba20e62004-07-31 16:15:44 +0000130 self.fail("""expected exception %(expected_exception)s not raised
131called %(func)r
132with args %(args)r
133and kwargs %(kwargs)r
134""" % locals ())
Greg Ward55493222003-04-21 02:41:25 +0000135
Greg Wardeba20e62004-07-31 16:15:44 +0000136
Greg Ward55493222003-04-21 02:41:25 +0000137 # -- Assertions used in more than one class --------------------
138
139 def assertParseFail(self, cmdline_args, expected_output):
Greg Ward48aa84b2004-10-27 02:20:04 +0000140 """
141 Assert the parser fails with the expected message. Caller
142 must ensure that self.parser is an InterceptingOptionParser.
143 """
Tim Peters579f7352004-07-31 21:14:28 +0000144 try:
Greg Ward48aa84b2004-10-27 02:20:04 +0000145 self.parser.parse_args(cmdline_args)
146 except InterceptedError, err:
147 self.assertEqual(err.error_message, expected_output)
148 else:
149 self.assertFalse("expected parse failure")
Greg Ward55493222003-04-21 02:41:25 +0000150
Greg Ward48aa84b2004-10-27 02:20:04 +0000151 def assertOutput(self,
152 cmdline_args,
153 expected_output,
154 expected_status=0,
155 expected_error=None):
Greg Ward55493222003-04-21 02:41:25 +0000156 """Assert the parser prints the expected output on stdout."""
Tim Peters579f7352004-07-31 21:14:28 +0000157 save_stdout = sys.stdout
Greg Ward0e0c9f42006-06-11 16:24:11 +0000158 encoding = getattr(save_stdout, 'encoding', None)
Tim Peters579f7352004-07-31 21:14:28 +0000159 try:
Greg Ward48aa84b2004-10-27 02:20:04 +0000160 try:
161 sys.stdout = StringIO()
Greg Ward0e0c9f42006-06-11 16:24:11 +0000162 if encoding:
163 sys.stdout.encoding = encoding
Greg Ward48aa84b2004-10-27 02:20:04 +0000164 self.parser.parse_args(cmdline_args)
165 finally:
166 output = sys.stdout.getvalue()
167 sys.stdout = save_stdout
Greg Ward55493222003-04-21 02:41:25 +0000168
Greg Ward48aa84b2004-10-27 02:20:04 +0000169 except InterceptedError, err:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000170 self.assertTrue(
Greg Ward0e0c9f42006-06-11 16:24:11 +0000171 type(output) is types.StringType,
172 "expected output to be an ordinary string, not %r"
173 % type(output))
174
Greg Wardab05edc2006-04-23 03:47:58 +0000175 if output != expected_output:
176 self.fail("expected: \n'''\n" + expected_output +
177 "'''\nbut got \n'''\n" + output + "'''")
Greg Ward48aa84b2004-10-27 02:20:04 +0000178 self.assertEqual(err.exit_status, expected_status)
179 self.assertEqual(err.exit_message, expected_error)
180 else:
181 self.assertFalse("expected parser.exit()")
182
183 def assertTypeError(self, func, expected_message, *args):
184 """Assert that TypeError is raised when executing func."""
185 self.assertRaises(func, args, None, TypeError, expected_message)
Greg Wardeba20e62004-07-31 16:15:44 +0000186
187 def assertHelp(self, parser, expected_help):
188 actual_help = parser.format_help()
189 if actual_help != expected_help:
190 raise self.failureException(
191 'help text failure; expected:\n"' +
192 expected_help + '"; got:\n"' +
193 actual_help + '"\n')
Greg Ward55493222003-04-21 02:41:25 +0000194
195# -- Test make_option() aka Option -------------------------------------
196
Greg Ward48aa84b2004-10-27 02:20:04 +0000197# It's not necessary to test correct options here. All the tests in the
Greg Ward55493222003-04-21 02:41:25 +0000198# parser.parse_args() section deal with those, because they're needed
Greg Ward48aa84b2004-10-27 02:20:04 +0000199# there.
Greg Ward55493222003-04-21 02:41:25 +0000200
201class TestOptionChecks(BaseTest):
202 def setUp(self):
203 self.parser = OptionParser(usage=SUPPRESS_USAGE)
204
Greg Ward48aa84b2004-10-27 02:20:04 +0000205 def assertOptionError(self, expected_message, args=[], kwargs={}):
Greg Wardeba20e62004-07-31 16:15:44 +0000206 self.assertRaises(make_option, args, kwargs,
Greg Ward48aa84b2004-10-27 02:20:04 +0000207 OptionError, expected_message)
Greg Ward55493222003-04-21 02:41:25 +0000208
209 def test_opt_string_empty(self):
210 self.assertTypeError(make_option,
211 "at least one option string must be supplied")
212
213 def test_opt_string_too_short(self):
Greg Ward48aa84b2004-10-27 02:20:04 +0000214 self.assertOptionError(
215 "invalid option string 'b': must be at least two characters long",
216 ["b"])
Greg Ward55493222003-04-21 02:41:25 +0000217
218 def test_opt_string_short_invalid(self):
Greg Ward48aa84b2004-10-27 02:20:04 +0000219 self.assertOptionError(
220 "invalid short option string '--': must be "
221 "of the form -x, (x any non-dash char)",
222 ["--"])
Greg Ward55493222003-04-21 02:41:25 +0000223
224 def test_opt_string_long_invalid(self):
Greg Ward48aa84b2004-10-27 02:20:04 +0000225 self.assertOptionError(
226 "invalid long option string '---': "
227 "must start with --, followed by non-dash",
228 ["---"])
Greg Ward55493222003-04-21 02:41:25 +0000229
230 def test_attr_invalid(self):
Greg Ward48aa84b2004-10-27 02:20:04 +0000231 self.assertOptionError(
Armin Rigoa3f09272006-05-28 19:13:17 +0000232 "option -b: invalid keyword arguments: bar, foo",
Greg Ward48aa84b2004-10-27 02:20:04 +0000233 ["-b"], {'foo': None, 'bar': None})
Greg Ward55493222003-04-21 02:41:25 +0000234
235 def test_action_invalid(self):
Greg Ward48aa84b2004-10-27 02:20:04 +0000236 self.assertOptionError(
237 "option -b: invalid action: 'foo'",
238 ["-b"], {'action': 'foo'})
Greg Ward55493222003-04-21 02:41:25 +0000239
240 def test_type_invalid(self):
Greg Ward48aa84b2004-10-27 02:20:04 +0000241 self.assertOptionError(
242 "option -b: invalid option type: 'foo'",
243 ["-b"], {'type': 'foo'})
244 self.assertOptionError(
245 "option -b: invalid option type: 'tuple'",
246 ["-b"], {'type': tuple})
Greg Ward55493222003-04-21 02:41:25 +0000247
248 def test_no_type_for_action(self):
Greg Ward48aa84b2004-10-27 02:20:04 +0000249 self.assertOptionError(
250 "option -b: must not supply a type for action 'count'",
251 ["-b"], {'action': 'count', 'type': 'int'})
Greg Ward55493222003-04-21 02:41:25 +0000252
253 def test_no_choices_list(self):
Greg Ward48aa84b2004-10-27 02:20:04 +0000254 self.assertOptionError(
255 "option -b/--bad: must supply a list of "
256 "choices for type 'choice'",
257 ["-b", "--bad"], {'type': "choice"})
Greg Ward55493222003-04-21 02:41:25 +0000258
259 def test_bad_choices_list(self):
260 typename = type('').__name__
Greg Ward48aa84b2004-10-27 02:20:04 +0000261 self.assertOptionError(
262 "option -b/--bad: choices must be a list of "
263 "strings ('%s' supplied)" % typename,
264 ["-b", "--bad"],
265 {'type': "choice", 'choices':"bad choices"})
Greg Ward55493222003-04-21 02:41:25 +0000266
267 def test_no_choices_for_type(self):
Greg Ward48aa84b2004-10-27 02:20:04 +0000268 self.assertOptionError(
269 "option -b: must not supply choices for type 'int'",
270 ["-b"], {'type': 'int', 'choices':"bad"})
Greg Ward55493222003-04-21 02:41:25 +0000271
272 def test_no_const_for_action(self):
Greg Ward48aa84b2004-10-27 02:20:04 +0000273 self.assertOptionError(
274 "option -b: 'const' must not be supplied for action 'store'",
275 ["-b"], {'action': 'store', 'const': 1})
Greg Ward55493222003-04-21 02:41:25 +0000276
277 def test_no_nargs_for_action(self):
Greg Ward48aa84b2004-10-27 02:20:04 +0000278 self.assertOptionError(
279 "option -b: 'nargs' must not be supplied for action 'count'",
280 ["-b"], {'action': 'count', 'nargs': 2})
Greg Ward55493222003-04-21 02:41:25 +0000281
282 def test_callback_not_callable(self):
Greg Ward48aa84b2004-10-27 02:20:04 +0000283 self.assertOptionError(
284 "option -b: callback not callable: 'foo'",
285 ["-b"], {'action': 'callback',
286 'callback': 'foo'})
Greg Ward55493222003-04-21 02:41:25 +0000287
288 def dummy(self):
289 pass
290
291 def test_callback_args_no_tuple(self):
Greg Ward48aa84b2004-10-27 02:20:04 +0000292 self.assertOptionError(
293 "option -b: callback_args, if supplied, "
294 "must be a tuple: not 'foo'",
295 ["-b"], {'action': 'callback',
296 'callback': self.dummy,
297 'callback_args': 'foo'})
Greg Ward55493222003-04-21 02:41:25 +0000298
299 def test_callback_kwargs_no_dict(self):
Greg Ward48aa84b2004-10-27 02:20:04 +0000300 self.assertOptionError(
301 "option -b: callback_kwargs, if supplied, "
302 "must be a dict: not 'foo'",
303 ["-b"], {'action': 'callback',
304 'callback': self.dummy,
305 'callback_kwargs': 'foo'})
Greg Ward55493222003-04-21 02:41:25 +0000306
307 def test_no_callback_for_action(self):
Greg Ward48aa84b2004-10-27 02:20:04 +0000308 self.assertOptionError(
309 "option -b: callback supplied ('foo') for non-callback option",
310 ["-b"], {'action': 'store',
311 'callback': 'foo'})
Greg Ward55493222003-04-21 02:41:25 +0000312
313 def test_no_callback_args_for_action(self):
Greg Ward48aa84b2004-10-27 02:20:04 +0000314 self.assertOptionError(
315 "option -b: callback_args supplied for non-callback option",
316 ["-b"], {'action': 'store',
317 'callback_args': 'foo'})
Greg Ward55493222003-04-21 02:41:25 +0000318
319 def test_no_callback_kwargs_for_action(self):
Greg Ward48aa84b2004-10-27 02:20:04 +0000320 self.assertOptionError(
321 "option -b: callback_kwargs supplied for non-callback option",
322 ["-b"], {'action': 'store',
323 'callback_kwargs': 'foo'})
Greg Ward55493222003-04-21 02:41:25 +0000324
325class TestOptionParser(BaseTest):
326 def setUp(self):
327 self.parser = OptionParser()
328 self.parser.add_option("-v", "--verbose", "-n", "--noisy",
329 action="store_true", dest="verbose")
330 self.parser.add_option("-q", "--quiet", "--silent",
331 action="store_false", dest="verbose")
332
333 def test_add_option_no_Option(self):
334 self.assertTypeError(self.parser.add_option,
335 "not an Option instance: None", None)
336
337 def test_add_option_invalid_arguments(self):
338 self.assertTypeError(self.parser.add_option,
339 "invalid arguments", None, None)
340
341 def test_get_option(self):
342 opt1 = self.parser.get_option("-v")
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000343 self.assertIsInstance(opt1, Option)
Greg Ward55493222003-04-21 02:41:25 +0000344 self.assertEqual(opt1._short_opts, ["-v", "-n"])
345 self.assertEqual(opt1._long_opts, ["--verbose", "--noisy"])
346 self.assertEqual(opt1.action, "store_true")
347 self.assertEqual(opt1.dest, "verbose")
348
349 def test_get_option_equals(self):
350 opt1 = self.parser.get_option("-v")
351 opt2 = self.parser.get_option("--verbose")
352 opt3 = self.parser.get_option("-n")
353 opt4 = self.parser.get_option("--noisy")
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000354 self.assertTrue(opt1 is opt2 is opt3 is opt4)
Greg Ward55493222003-04-21 02:41:25 +0000355
356 def test_has_option(self):
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000357 self.assertTrue(self.parser.has_option("-v"))
358 self.assertTrue(self.parser.has_option("--verbose"))
Greg Ward55493222003-04-21 02:41:25 +0000359
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000360 def assertTrueremoved(self):
361 self.assertTrue(self.parser.get_option("-v") is None)
362 self.assertTrue(self.parser.get_option("--verbose") is None)
363 self.assertTrue(self.parser.get_option("-n") is None)
364 self.assertTrue(self.parser.get_option("--noisy") is None)
Greg Ward55493222003-04-21 02:41:25 +0000365
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000366 self.assertFalse(self.parser.has_option("-v"))
367 self.assertFalse(self.parser.has_option("--verbose"))
368 self.assertFalse(self.parser.has_option("-n"))
369 self.assertFalse(self.parser.has_option("--noisy"))
Greg Ward55493222003-04-21 02:41:25 +0000370
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000371 self.assertTrue(self.parser.has_option("-q"))
372 self.assertTrue(self.parser.has_option("--silent"))
Greg Ward55493222003-04-21 02:41:25 +0000373
374 def test_remove_short_opt(self):
375 self.parser.remove_option("-n")
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000376 self.assertTrueremoved()
Greg Ward55493222003-04-21 02:41:25 +0000377
378 def test_remove_long_opt(self):
379 self.parser.remove_option("--verbose")
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000380 self.assertTrueremoved()
Greg Ward55493222003-04-21 02:41:25 +0000381
382 def test_remove_nonexistent(self):
Greg Wardeba20e62004-07-31 16:15:44 +0000383 self.assertRaises(self.parser.remove_option, ('foo',), None,
384 ValueError, "no such option 'foo'")
385
Andrew Kuchlingcb4069c2014-04-15 16:44:43 -0400386 @test_support.impl_detail('Relies on sys.getrefcount', cpython=True)
Greg Wardab05edc2006-04-23 03:47:58 +0000387 def test_refleak(self):
388 # If an OptionParser is carrying around a reference to a large
389 # object, various cycles can prevent it from being GC'd in
390 # a timely fashion. destroy() breaks the cycles to ensure stuff
391 # can be cleaned up.
392 big_thing = [42]
393 refcount = sys.getrefcount(big_thing)
394 parser = OptionParser()
395 parser.add_option("-a", "--aaarggh")
396 parser.big_thing = big_thing
397
398 parser.destroy()
399 #self.assertEqual(refcount, sys.getrefcount(big_thing))
400 del parser
401 self.assertEqual(refcount, sys.getrefcount(big_thing))
402
403
Greg Ward48aa84b2004-10-27 02:20:04 +0000404class TestOptionValues(BaseTest):
405 def setUp(self):
406 pass
407
408 def test_basics(self):
409 values = Values()
410 self.assertEqual(vars(values), {})
411 self.assertEqual(values, {})
412 self.assertNotEqual(values, {"foo": "bar"})
413 self.assertNotEqual(values, "")
414
415 dict = {"foo": "bar", "baz": 42}
416 values = Values(defaults=dict)
417 self.assertEqual(vars(values), dict)
418 self.assertEqual(values, dict)
419 self.assertNotEqual(values, {"foo": "bar"})
420 self.assertNotEqual(values, {})
421 self.assertNotEqual(values, "")
422 self.assertNotEqual(values, [])
423
424
Greg Wardeba20e62004-07-31 16:15:44 +0000425class TestTypeAliases(BaseTest):
426 def setUp(self):
427 self.parser = OptionParser()
428
Greg Wardab05edc2006-04-23 03:47:58 +0000429 def test_str_aliases_string(self):
430 self.parser.add_option("-s", type="str")
Ezio Melotti2623a372010-11-21 13:34:58 +0000431 self.assertEqual(self.parser.get_option("-s").type, "string")
Greg Wardab05edc2006-04-23 03:47:58 +0000432
433 def test_new_type_object(self):
434 self.parser.add_option("-s", type=str)
Ezio Melotti2623a372010-11-21 13:34:58 +0000435 self.assertEqual(self.parser.get_option("-s").type, "string")
Greg Wardab05edc2006-04-23 03:47:58 +0000436 self.parser.add_option("-x", type=int)
Ezio Melotti2623a372010-11-21 13:34:58 +0000437 self.assertEqual(self.parser.get_option("-x").type, "int")
Greg Wardab05edc2006-04-23 03:47:58 +0000438
439 def test_old_type_object(self):
440 self.parser.add_option("-s", type=types.StringType)
Ezio Melotti2623a372010-11-21 13:34:58 +0000441 self.assertEqual(self.parser.get_option("-s").type, "string")
Greg Wardab05edc2006-04-23 03:47:58 +0000442 self.parser.add_option("-x", type=types.IntType)
Ezio Melotti2623a372010-11-21 13:34:58 +0000443 self.assertEqual(self.parser.get_option("-x").type, "int")
Tim Peters10d59f32004-10-27 02:43:25 +0000444
Greg Wardeba20e62004-07-31 16:15:44 +0000445
446# Custom type for testing processing of default values.
447_time_units = { 's' : 1, 'm' : 60, 'h' : 60*60, 'd' : 60*60*24 }
448
449def _check_duration(option, opt, value):
450 try:
451 if value[-1].isdigit():
452 return int(value)
453 else:
454 return int(value[:-1]) * _time_units[value[-1]]
Georg Brandlb3cda982010-02-07 12:19:43 +0000455 except (ValueError, IndexError):
Greg Wardeba20e62004-07-31 16:15:44 +0000456 raise OptionValueError(
457 'option %s: invalid duration: %r' % (opt, value))
458
459class DurationOption(Option):
460 TYPES = Option.TYPES + ('duration',)
461 TYPE_CHECKER = copy.copy(Option.TYPE_CHECKER)
462 TYPE_CHECKER['duration'] = _check_duration
463
464class TestDefaultValues(BaseTest):
465 def setUp(self):
466 self.parser = OptionParser()
467 self.parser.add_option("-v", "--verbose", default=True)
468 self.parser.add_option("-q", "--quiet", dest='verbose')
469 self.parser.add_option("-n", type="int", default=37)
470 self.parser.add_option("-m", type="int")
471 self.parser.add_option("-s", default="foo")
472 self.parser.add_option("-t")
473 self.parser.add_option("-u", default=None)
474 self.expected = { 'verbose': True,
475 'n': 37,
476 'm': None,
477 's': "foo",
478 't': None,
479 'u': None }
480
481 def test_basic_defaults(self):
482 self.assertEqual(self.parser.get_default_values(), self.expected)
483
484 def test_mixed_defaults_post(self):
485 self.parser.set_defaults(n=42, m=-100)
486 self.expected.update({'n': 42, 'm': -100})
487 self.assertEqual(self.parser.get_default_values(), self.expected)
488
489 def test_mixed_defaults_pre(self):
490 self.parser.set_defaults(x="barf", y="blah")
491 self.parser.add_option("-x", default="frob")
492 self.parser.add_option("-y")
493
494 self.expected.update({'x': "frob", 'y': "blah"})
495 self.assertEqual(self.parser.get_default_values(), self.expected)
496
497 self.parser.remove_option("-y")
498 self.parser.add_option("-y", default=None)
499 self.expected.update({'y': None})
500 self.assertEqual(self.parser.get_default_values(), self.expected)
501
502 def test_process_default(self):
503 self.parser.option_class = DurationOption
504 self.parser.add_option("-d", type="duration", default=300)
505 self.parser.add_option("-e", type="duration", default="6m")
506 self.parser.set_defaults(n="42")
507 self.expected.update({'d': 300, 'e': 360, 'n': 42})
508 self.assertEqual(self.parser.get_default_values(), self.expected)
509
510 self.parser.set_process_default_values(False)
511 self.expected.update({'d': 300, 'e': "6m", 'n': "42"})
512 self.assertEqual(self.parser.get_default_values(), self.expected)
513
514
515class TestProgName(BaseTest):
516 """
517 Test that %prog expands to the right thing in usage, version,
518 and help strings.
519 """
520
521 def assertUsage(self, parser, expected_usage):
522 self.assertEqual(parser.get_usage(), expected_usage)
523
524 def assertVersion(self, parser, expected_version):
525 self.assertEqual(parser.get_version(), expected_version)
526
527
528 def test_default_progname(self):
529 # Make sure that program name taken from sys.argv[0] by default.
Tim Peters579f7352004-07-31 21:14:28 +0000530 save_argv = sys.argv[:]
531 try:
Greg Ward48aa84b2004-10-27 02:20:04 +0000532 sys.argv[0] = os.path.join("foo", "bar", "baz.py")
Greg Wardab05edc2006-04-23 03:47:58 +0000533 parser = OptionParser("%prog ...", version="%prog 1.2")
534 expected_usage = "Usage: baz.py ...\n"
Tim Peters579f7352004-07-31 21:14:28 +0000535 self.assertUsage(parser, expected_usage)
536 self.assertVersion(parser, "baz.py 1.2")
537 self.assertHelp(parser,
Greg Ward48aa84b2004-10-27 02:20:04 +0000538 expected_usage + "\n" +
Greg Wardab05edc2006-04-23 03:47:58 +0000539 "Options:\n"
Greg Ward48aa84b2004-10-27 02:20:04 +0000540 " --version show program's version number and exit\n"
541 " -h, --help show this help message and exit\n")
Tim Peters579f7352004-07-31 21:14:28 +0000542 finally:
543 sys.argv[:] = save_argv
Greg Wardeba20e62004-07-31 16:15:44 +0000544
545 def test_custom_progname(self):
546 parser = OptionParser(prog="thingy",
547 version="%prog 0.1",
548 usage="%prog arg arg")
549 parser.remove_option("-h")
550 parser.remove_option("--version")
Greg Wardab05edc2006-04-23 03:47:58 +0000551 expected_usage = "Usage: thingy arg arg\n"
Greg Wardeba20e62004-07-31 16:15:44 +0000552 self.assertUsage(parser, expected_usage)
553 self.assertVersion(parser, "thingy 0.1")
554 self.assertHelp(parser, expected_usage + "\n")
555
556
557class TestExpandDefaults(BaseTest):
558 def setUp(self):
559 self.parser = OptionParser(prog="test")
560 self.help_prefix = """\
Greg Wardab05edc2006-04-23 03:47:58 +0000561Usage: test [options]
Greg Wardeba20e62004-07-31 16:15:44 +0000562
Greg Wardab05edc2006-04-23 03:47:58 +0000563Options:
Greg Wardeba20e62004-07-31 16:15:44 +0000564 -h, --help show this help message and exit
565"""
566 self.file_help = "read from FILE [default: %default]"
567 self.expected_help_file = self.help_prefix + \
568 " -f FILE, --file=FILE read from FILE [default: foo.txt]\n"
569 self.expected_help_none = self.help_prefix + \
570 " -f FILE, --file=FILE read from FILE [default: none]\n"
571
572 def test_option_default(self):
573 self.parser.add_option("-f", "--file",
574 default="foo.txt",
575 help=self.file_help)
576 self.assertHelp(self.parser, self.expected_help_file)
577
578 def test_parser_default_1(self):
579 self.parser.add_option("-f", "--file",
580 help=self.file_help)
581 self.parser.set_default('file', "foo.txt")
582 self.assertHelp(self.parser, self.expected_help_file)
583
584 def test_parser_default_2(self):
585 self.parser.add_option("-f", "--file",
586 help=self.file_help)
587 self.parser.set_defaults(file="foo.txt")
588 self.assertHelp(self.parser, self.expected_help_file)
589
590 def test_no_default(self):
591 self.parser.add_option("-f", "--file",
592 help=self.file_help)
593 self.assertHelp(self.parser, self.expected_help_none)
594
595 def test_default_none_1(self):
596 self.parser.add_option("-f", "--file",
597 default=None,
598 help=self.file_help)
599 self.assertHelp(self.parser, self.expected_help_none)
Tim Peters10d59f32004-10-27 02:43:25 +0000600
Greg Wardeba20e62004-07-31 16:15:44 +0000601 def test_default_none_2(self):
602 self.parser.add_option("-f", "--file",
603 help=self.file_help)
604 self.parser.set_defaults(file=None)
605 self.assertHelp(self.parser, self.expected_help_none)
606
607 def test_float_default(self):
608 self.parser.add_option(
609 "-p", "--prob",
610 help="blow up with probability PROB [default: %default]")
611 self.parser.set_defaults(prob=0.43)
612 expected_help = self.help_prefix + \
613 " -p PROB, --prob=PROB blow up with probability PROB [default: 0.43]\n"
614 self.assertHelp(self.parser, expected_help)
615
616 def test_alt_expand(self):
617 self.parser.add_option("-f", "--file",
618 default="foo.txt",
619 help="read from FILE [default: *DEFAULT*]")
620 self.parser.formatter.default_tag = "*DEFAULT*"
621 self.assertHelp(self.parser, self.expected_help_file)
622
623 def test_no_expand(self):
624 self.parser.add_option("-f", "--file",
625 default="foo.txt",
626 help="read from %default file")
627 self.parser.formatter.default_tag = None
628 expected_help = self.help_prefix + \
629 " -f FILE, --file=FILE read from %default file\n"
630 self.assertHelp(self.parser, expected_help)
631
Greg Ward55493222003-04-21 02:41:25 +0000632
633# -- Test parser.parse_args() ------------------------------------------
634
635class TestStandard(BaseTest):
636 def setUp(self):
637 options = [make_option("-a", type="string"),
638 make_option("-b", "--boo", type="int", dest='boo'),
639 make_option("--foo", action="append")]
640
Greg Ward48aa84b2004-10-27 02:20:04 +0000641 self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE,
642 option_list=options)
Greg Ward55493222003-04-21 02:41:25 +0000643
644 def test_required_value(self):
Greg Wardeba20e62004-07-31 16:15:44 +0000645 self.assertParseFail(["-a"], "-a option requires an argument")
Greg Ward55493222003-04-21 02:41:25 +0000646
647 def test_invalid_integer(self):
648 self.assertParseFail(["-b", "5x"],
649 "option -b: invalid integer value: '5x'")
650
651 def test_no_such_option(self):
652 self.assertParseFail(["--boo13"], "no such option: --boo13")
653
654 def test_long_invalid_integer(self):
655 self.assertParseFail(["--boo=x5"],
656 "option --boo: invalid integer value: 'x5'")
657
658 def test_empty(self):
659 self.assertParseOK([], {'a': None, 'boo': None, 'foo': None}, [])
660
661 def test_shortopt_empty_longopt_append(self):
662 self.assertParseOK(["-a", "", "--foo=blah", "--foo="],
663 {'a': "", 'boo': None, 'foo': ["blah", ""]},
664 [])
665
666 def test_long_option_append(self):
667 self.assertParseOK(["--foo", "bar", "--foo", "", "--foo=x"],
668 {'a': None,
669 'boo': None,
670 'foo': ["bar", "", "x"]},
671 [])
672
673 def test_option_argument_joined(self):
674 self.assertParseOK(["-abc"],
675 {'a': "bc", 'boo': None, 'foo': None},
676 [])
677
678 def test_option_argument_split(self):
679 self.assertParseOK(["-a", "34"],
680 {'a': "34", 'boo': None, 'foo': None},
681 [])
682
683 def test_option_argument_joined_integer(self):
684 self.assertParseOK(["-b34"],
685 {'a': None, 'boo': 34, 'foo': None},
686 [])
687
688 def test_option_argument_split_negative_integer(self):
689 self.assertParseOK(["-b", "-5"],
690 {'a': None, 'boo': -5, 'foo': None},
691 [])
692
693 def test_long_option_argument_joined(self):
694 self.assertParseOK(["--boo=13"],
695 {'a': None, 'boo': 13, 'foo': None},
696 [])
697
698 def test_long_option_argument_split(self):
699 self.assertParseOK(["--boo", "111"],
700 {'a': None, 'boo': 111, 'foo': None},
701 [])
702
703 def test_long_option_short_option(self):
704 self.assertParseOK(["--foo=bar", "-axyz"],
705 {'a': 'xyz', 'boo': None, 'foo': ["bar"]},
706 [])
707
708 def test_abbrev_long_option(self):
709 self.assertParseOK(["--f=bar", "-axyz"],
710 {'a': 'xyz', 'boo': None, 'foo': ["bar"]},
711 [])
712
713 def test_defaults(self):
714 (options, args) = self.parser.parse_args([])
715 defaults = self.parser.get_default_values()
716 self.assertEqual(vars(defaults), vars(options))
717
718 def test_ambiguous_option(self):
719 self.parser.add_option("--foz", action="store",
720 type="string", dest="foo")
Greg Ward55493222003-04-21 02:41:25 +0000721 self.assertParseFail(["--f=bar"],
Armin Rigoa3f09272006-05-28 19:13:17 +0000722 "ambiguous option: --f (--foo, --foz?)")
Greg Ward55493222003-04-21 02:41:25 +0000723
724
725 def test_short_and_long_option_split(self):
726 self.assertParseOK(["-a", "xyz", "--foo", "bar"],
727 {'a': 'xyz', 'boo': None, 'foo': ["bar"]},
728 []),
729
730 def test_short_option_split_long_option_append(self):
731 self.assertParseOK(["--foo=bar", "-b", "123", "--foo", "baz"],
732 {'a': None, 'boo': 123, 'foo': ["bar", "baz"]},
733 [])
734
735 def test_short_option_split_one_positional_arg(self):
736 self.assertParseOK(["-a", "foo", "bar"],
737 {'a': "foo", 'boo': None, 'foo': None},
738 ["bar"]),
739
740 def test_short_option_consumes_separator(self):
741 self.assertParseOK(["-a", "--", "foo", "bar"],
742 {'a': "--", 'boo': None, 'foo': None},
743 ["foo", "bar"]),
Greg Wardab05edc2006-04-23 03:47:58 +0000744 self.assertParseOK(["-a", "--", "--foo", "bar"],
745 {'a': "--", 'boo': None, 'foo': ["bar"]},
746 []),
Greg Ward55493222003-04-21 02:41:25 +0000747
748 def test_short_option_joined_and_separator(self):
749 self.assertParseOK(["-ab", "--", "--foo", "bar"],
750 {'a': "b", 'boo': None, 'foo': None},
751 ["--foo", "bar"]),
752
Greg Wardab05edc2006-04-23 03:47:58 +0000753 def test_hyphen_becomes_positional_arg(self):
Greg Ward55493222003-04-21 02:41:25 +0000754 self.assertParseOK(["-ab", "-", "--foo", "bar"],
755 {'a': "b", 'boo': None, 'foo': ["bar"]},
756 ["-"])
757
758 def test_no_append_versus_append(self):
759 self.assertParseOK(["-b3", "-b", "5", "--foo=bar", "--foo", "baz"],
760 {'a': None, 'boo': 5, 'foo': ["bar", "baz"]},
761 [])
762
763 def test_option_consumes_optionlike_string(self):
764 self.assertParseOK(["-a", "-b3"],
765 {'a': "-b3", 'boo': None, 'foo': None},
766 [])
767
R. David Murray32e06812010-06-26 00:06:44 +0000768 def test_combined_single_invalid_option(self):
769 self.parser.add_option("-t", action="store_true")
770 self.assertParseFail(["-test"],
R. David Murray04a34392010-06-26 03:27:32 +0000771 "no such option: -e")
R. David Murray32e06812010-06-26 00:06:44 +0000772
R David Murray7cd8b422012-08-14 09:14:37 -0400773 def test_add_option_accepts_unicode(self):
774 self.parser.add_option(u"-u", u"--unicode", action="store_true")
775 self.assertParseOK(["-u"],
776 {'a': None, 'boo': None, 'foo': None, 'unicode': True},
777 [])
778
R David Murrayfe9efc52012-08-13 22:04:30 -0400779
Greg Ward55493222003-04-21 02:41:25 +0000780class TestBool(BaseTest):
781 def setUp(self):
782 options = [make_option("-v",
783 "--verbose",
784 action="store_true",
785 dest="verbose",
786 default=''),
787 make_option("-q",
788 "--quiet",
789 action="store_false",
790 dest="verbose")]
791 self.parser = OptionParser(option_list = options)
792
793 def test_bool_default(self):
794 self.assertParseOK([],
795 {'verbose': ''},
796 [])
797
798 def test_bool_false(self):
799 (options, args) = self.assertParseOK(["-q"],
800 {'verbose': 0},
801 [])
Georg Brandle2773252010-08-01 19:14:56 +0000802 self.assertTrue(options.verbose is False)
Greg Ward55493222003-04-21 02:41:25 +0000803
804 def test_bool_true(self):
805 (options, args) = self.assertParseOK(["-v"],
806 {'verbose': 1},
807 [])
Georg Brandle2773252010-08-01 19:14:56 +0000808 self.assertTrue(options.verbose is True)
Greg Ward55493222003-04-21 02:41:25 +0000809
810 def test_bool_flicker_on_and_off(self):
811 self.assertParseOK(["-qvq", "-q", "-v"],
812 {'verbose': 1},
813 [])
814
815class TestChoice(BaseTest):
816 def setUp(self):
Greg Ward48aa84b2004-10-27 02:20:04 +0000817 self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE)
Greg Ward55493222003-04-21 02:41:25 +0000818 self.parser.add_option("-c", action="store", type="choice",
819 dest="choice", choices=["one", "two", "three"])
820
821 def test_valid_choice(self):
822 self.assertParseOK(["-c", "one", "xyz"],
823 {'choice': 'one'},
824 ["xyz"])
825
826 def test_invalid_choice(self):
827 self.assertParseFail(["-c", "four", "abc"],
828 "option -c: invalid choice: 'four' "
829 "(choose from 'one', 'two', 'three')")
830
831 def test_add_choice_option(self):
832 self.parser.add_option("-d", "--default",
833 choices=["four", "five", "six"])
834 opt = self.parser.get_option("-d")
835 self.assertEqual(opt.type, "choice")
836 self.assertEqual(opt.action, "store")
837
838class TestCount(BaseTest):
839 def setUp(self):
Greg Ward48aa84b2004-10-27 02:20:04 +0000840 self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE)
Greg Ward55493222003-04-21 02:41:25 +0000841 self.v_opt = make_option("-v", action="count", dest="verbose")
842 self.parser.add_option(self.v_opt)
843 self.parser.add_option("--verbose", type="int", dest="verbose")
844 self.parser.add_option("-q", "--quiet",
845 action="store_const", dest="verbose", const=0)
846
847 def test_empty(self):
848 self.assertParseOK([], {'verbose': None}, [])
849
850 def test_count_one(self):
851 self.assertParseOK(["-v"], {'verbose': 1}, [])
852
853 def test_count_three(self):
854 self.assertParseOK(["-vvv"], {'verbose': 3}, [])
855
856 def test_count_three_apart(self):
857 self.assertParseOK(["-v", "-v", "-v"], {'verbose': 3}, [])
858
859 def test_count_override_amount(self):
860 self.assertParseOK(["-vvv", "--verbose=2"], {'verbose': 2}, [])
861
862 def test_count_override_quiet(self):
863 self.assertParseOK(["-vvv", "--verbose=2", "-q"], {'verbose': 0}, [])
864
865 def test_count_overriding(self):
866 self.assertParseOK(["-vvv", "--verbose=2", "-q", "-v"],
867 {'verbose': 1}, [])
868
869 def test_count_interspersed_args(self):
870 self.assertParseOK(["--quiet", "3", "-v"],
871 {'verbose': 1},
872 ["3"])
873
874 def test_count_no_interspersed_args(self):
875 self.parser.disable_interspersed_args()
876 self.assertParseOK(["--quiet", "3", "-v"],
877 {'verbose': 0},
878 ["3", "-v"])
879
880 def test_count_no_such_option(self):
881 self.assertParseFail(["-q3", "-v"], "no such option: -3")
882
883 def test_count_option_no_value(self):
884 self.assertParseFail(["--quiet=3", "-v"],
885 "--quiet option does not take a value")
886
887 def test_count_with_default(self):
888 self.parser.set_default('verbose', 0)
889 self.assertParseOK([], {'verbose':0}, [])
890
891 def test_count_overriding_default(self):
892 self.parser.set_default('verbose', 0)
893 self.assertParseOK(["-vvv", "--verbose=2", "-q", "-v"],
894 {'verbose': 1}, [])
895
Greg Ward48aa84b2004-10-27 02:20:04 +0000896class TestMultipleArgs(BaseTest):
Greg Ward55493222003-04-21 02:41:25 +0000897 def setUp(self):
Greg Ward48aa84b2004-10-27 02:20:04 +0000898 self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE)
Greg Ward55493222003-04-21 02:41:25 +0000899 self.parser.add_option("-p", "--point",
900 action="store", nargs=3, type="float", dest="point")
901
902 def test_nargs_with_positional_args(self):
903 self.assertParseOK(["foo", "-p", "1", "2.5", "-4.3", "xyz"],
904 {'point': (1.0, 2.5, -4.3)},
905 ["foo", "xyz"])
906
907 def test_nargs_long_opt(self):
908 self.assertParseOK(["--point", "-1", "2.5", "-0", "xyz"],
909 {'point': (-1.0, 2.5, -0.0)},
910 ["xyz"])
911
912 def test_nargs_invalid_float_value(self):
913 self.assertParseFail(["-p", "1.0", "2x", "3.5"],
914 "option -p: "
915 "invalid floating-point value: '2x'")
916
917 def test_nargs_required_values(self):
918 self.assertParseFail(["--point", "1.0", "3.5"],
Greg Wardeba20e62004-07-31 16:15:44 +0000919 "--point option requires 3 arguments")
Greg Ward55493222003-04-21 02:41:25 +0000920
Greg Ward48aa84b2004-10-27 02:20:04 +0000921class TestMultipleArgsAppend(BaseTest):
Greg Ward55493222003-04-21 02:41:25 +0000922 def setUp(self):
Greg Ward48aa84b2004-10-27 02:20:04 +0000923 self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE)
Greg Ward55493222003-04-21 02:41:25 +0000924 self.parser.add_option("-p", "--point", action="store", nargs=3,
925 type="float", dest="point")
926 self.parser.add_option("-f", "--foo", action="append", nargs=2,
927 type="int", dest="foo")
Greg Wardab05edc2006-04-23 03:47:58 +0000928 self.parser.add_option("-z", "--zero", action="append_const",
929 dest="foo", const=(0, 0))
Greg Ward55493222003-04-21 02:41:25 +0000930
931 def test_nargs_append(self):
932 self.assertParseOK(["-f", "4", "-3", "blah", "--foo", "1", "666"],
933 {'point': None, 'foo': [(4, -3), (1, 666)]},
934 ["blah"])
935
936 def test_nargs_append_required_values(self):
937 self.assertParseFail(["-f4,3"],
Greg Wardeba20e62004-07-31 16:15:44 +0000938 "-f option requires 2 arguments")
Greg Ward55493222003-04-21 02:41:25 +0000939
940 def test_nargs_append_simple(self):
941 self.assertParseOK(["--foo=3", "4"],
942 {'point': None, 'foo':[(3, 4)]},
943 [])
944
Greg Wardab05edc2006-04-23 03:47:58 +0000945 def test_nargs_append_const(self):
946 self.assertParseOK(["--zero", "--foo", "3", "4", "-z"],
947 {'point': None, 'foo':[(0, 0), (3, 4), (0, 0)]},
948 [])
949
Greg Ward55493222003-04-21 02:41:25 +0000950class TestVersion(BaseTest):
951 def test_version(self):
Greg Ward48aa84b2004-10-27 02:20:04 +0000952 self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE,
953 version="%prog 0.1")
954 save_argv = sys.argv[:]
955 try:
956 sys.argv[0] = os.path.join(os.curdir, "foo", "bar")
957 self.assertOutput(["--version"], "bar 0.1\n")
958 finally:
959 sys.argv[:] = save_argv
Greg Ward55493222003-04-21 02:41:25 +0000960
961 def test_no_version(self):
Greg Ward48aa84b2004-10-27 02:20:04 +0000962 self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE)
Greg Ward55493222003-04-21 02:41:25 +0000963 self.assertParseFail(["--version"],
964 "no such option: --version")
965
966# -- Test conflicting default values and parser.parse_args() -----------
967
968class TestConflictingDefaults(BaseTest):
969 """Conflicting default values: the last one should win."""
970 def setUp(self):
971 self.parser = OptionParser(option_list=[
972 make_option("-v", action="store_true", dest="verbose", default=1)])
973
974 def test_conflict_default(self):
975 self.parser.add_option("-q", action="store_false", dest="verbose",
976 default=0)
977 self.assertParseOK([], {'verbose': 0}, [])
978
979 def test_conflict_default_none(self):
980 self.parser.add_option("-q", action="store_false", dest="verbose",
981 default=None)
982 self.assertParseOK([], {'verbose': None}, [])
983
984class TestOptionGroup(BaseTest):
985 def setUp(self):
986 self.parser = OptionParser(usage=SUPPRESS_USAGE)
987
988 def test_option_group_create_instance(self):
989 group = OptionGroup(self.parser, "Spam")
990 self.parser.add_option_group(group)
991 group.add_option("--spam", action="store_true",
992 help="spam spam spam spam")
993 self.assertParseOK(["--spam"], {'spam': 1}, [])
994
995 def test_add_group_no_group(self):
996 self.assertTypeError(self.parser.add_option_group,
997 "not an OptionGroup instance: None", None)
998
999 def test_add_group_invalid_arguments(self):
1000 self.assertTypeError(self.parser.add_option_group,
1001 "invalid arguments", None, None)
1002
1003 def test_add_group_wrong_parser(self):
1004 group = OptionGroup(self.parser, "Spam")
1005 group.parser = OptionParser()
Greg Wardeba20e62004-07-31 16:15:44 +00001006 self.assertRaises(self.parser.add_option_group, (group,), None,
1007 ValueError, "invalid OptionGroup (wrong parser)")
Greg Ward55493222003-04-21 02:41:25 +00001008
1009 def test_group_manipulate(self):
1010 group = self.parser.add_option_group("Group 2",
1011 description="Some more options")
1012 group.set_title("Bacon")
1013 group.add_option("--bacon", type="int")
Benjamin Peterson5c8da862009-06-30 22:57:08 +00001014 self.assertTrue(self.parser.get_option_group("--bacon"), group)
Greg Ward55493222003-04-21 02:41:25 +00001015
1016# -- Test extending and parser.parse_args() ----------------------------
1017
1018class TestExtendAddTypes(BaseTest):
1019 def setUp(self):
Greg Ward48aa84b2004-10-27 02:20:04 +00001020 self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE,
1021 option_class=self.MyOption)
Greg Ward55493222003-04-21 02:41:25 +00001022 self.parser.add_option("-a", None, type="string", dest="a")
1023 self.parser.add_option("-f", "--file", type="file", dest="file")
1024
Greg Wardab05edc2006-04-23 03:47:58 +00001025 def tearDown(self):
1026 if os.path.isdir(test_support.TESTFN):
1027 os.rmdir(test_support.TESTFN)
1028 elif os.path.isfile(test_support.TESTFN):
1029 os.unlink(test_support.TESTFN)
1030
Greg Ward55493222003-04-21 02:41:25 +00001031 class MyOption (Option):
Greg Wardab05edc2006-04-23 03:47:58 +00001032 def check_file(option, opt, value):
Greg Ward55493222003-04-21 02:41:25 +00001033 if not os.path.exists(value):
1034 raise OptionValueError("%s: file does not exist" % value)
1035 elif not os.path.isfile(value):
1036 raise OptionValueError("%s: not a regular file" % value)
1037 return value
1038
1039 TYPES = Option.TYPES + ("file",)
1040 TYPE_CHECKER = copy.copy(Option.TYPE_CHECKER)
1041 TYPE_CHECKER["file"] = check_file
1042
Greg Wardab05edc2006-04-23 03:47:58 +00001043 def test_filetype_ok(self):
Greg Ward55493222003-04-21 02:41:25 +00001044 open(test_support.TESTFN, "w").close()
1045 self.assertParseOK(["--file", test_support.TESTFN, "-afoo"],
1046 {'file': test_support.TESTFN, 'a': 'foo'},
1047 [])
1048
Greg Wardab05edc2006-04-23 03:47:58 +00001049 def test_filetype_noexist(self):
Greg Ward55493222003-04-21 02:41:25 +00001050 self.assertParseFail(["--file", test_support.TESTFN, "-afoo"],
1051 "%s: file does not exist" %
1052 test_support.TESTFN)
1053
Greg Wardab05edc2006-04-23 03:47:58 +00001054 def test_filetype_notfile(self):
Greg Ward55493222003-04-21 02:41:25 +00001055 os.mkdir(test_support.TESTFN)
1056 self.assertParseFail(["--file", test_support.TESTFN, "-afoo"],
1057 "%s: not a regular file" %
1058 test_support.TESTFN)
Greg Wardab05edc2006-04-23 03:47:58 +00001059
Greg Ward55493222003-04-21 02:41:25 +00001060
1061class TestExtendAddActions(BaseTest):
1062 def setUp(self):
1063 options = [self.MyOption("-a", "--apple", action="extend",
1064 type="string", dest="apple")]
1065 self.parser = OptionParser(option_list=options)
1066
1067 class MyOption (Option):
1068 ACTIONS = Option.ACTIONS + ("extend",)
1069 STORE_ACTIONS = Option.STORE_ACTIONS + ("extend",)
1070 TYPED_ACTIONS = Option.TYPED_ACTIONS + ("extend",)
1071
Greg Wardab05edc2006-04-23 03:47:58 +00001072 def take_action(self, action, dest, opt, value, values, parser):
Greg Ward55493222003-04-21 02:41:25 +00001073 if action == "extend":
1074 lvalue = value.split(",")
1075 values.ensure_value(dest, []).extend(lvalue)
1076 else:
1077 Option.take_action(self, action, dest, opt, parser, value,
1078 values)
1079
1080 def test_extend_add_action(self):
1081 self.assertParseOK(["-afoo,bar", "--apple=blah"],
1082 {'apple': ["foo", "bar", "blah"]},
1083 [])
1084
1085 def test_extend_add_action_normal(self):
1086 self.assertParseOK(["-a", "foo", "-abar", "--apple=x,y"],
1087 {'apple': ["foo", "bar", "x", "y"]},
1088 [])
1089
1090# -- Test callbacks and parser.parse_args() ----------------------------
1091
1092class TestCallback(BaseTest):
1093 def setUp(self):
1094 options = [make_option("-x",
1095 None,
1096 action="callback",
1097 callback=self.process_opt),
1098 make_option("-f",
1099 "--file",
1100 action="callback",
1101 callback=self.process_opt,
1102 type="string",
1103 dest="filename")]
1104 self.parser = OptionParser(option_list=options)
1105
1106 def process_opt(self, option, opt, value, parser_):
1107 if opt == "-x":
1108 self.assertEqual(option._short_opts, ["-x"])
1109 self.assertEqual(option._long_opts, [])
Benjamin Peterson5c8da862009-06-30 22:57:08 +00001110 self.assertTrue(parser_ is self.parser)
1111 self.assertTrue(value is None)
Greg Ward55493222003-04-21 02:41:25 +00001112 self.assertEqual(vars(parser_.values), {'filename': None})
1113
1114 parser_.values.x = 42
1115 elif opt == "--file":
1116 self.assertEqual(option._short_opts, ["-f"])
1117 self.assertEqual(option._long_opts, ["--file"])
Benjamin Peterson5c8da862009-06-30 22:57:08 +00001118 self.assertTrue(parser_ is self.parser)
Greg Ward55493222003-04-21 02:41:25 +00001119 self.assertEqual(value, "foo")
1120 self.assertEqual(vars(parser_.values), {'filename': None, 'x': 42})
1121
1122 setattr(parser_.values, option.dest, value)
1123 else:
1124 self.fail("Unknown option %r in process_opt." % opt)
1125
1126 def test_callback(self):
1127 self.assertParseOK(["-x", "--file=foo"],
1128 {'filename': "foo", 'x': 42},
1129 [])
1130
Greg Wardeba20e62004-07-31 16:15:44 +00001131 def test_callback_help(self):
1132 # This test was prompted by SF bug #960515 -- the point is
1133 # not to inspect the help text, just to make sure that
1134 # format_help() doesn't crash.
1135 parser = OptionParser(usage=SUPPRESS_USAGE)
1136 parser.remove_option("-h")
1137 parser.add_option("-t", "--test", action="callback",
1138 callback=lambda: None, type="string",
1139 help="foo")
1140
Greg Wardab05edc2006-04-23 03:47:58 +00001141 expected_help = ("Options:\n"
Greg Wardeba20e62004-07-31 16:15:44 +00001142 " -t TEST, --test=TEST foo\n")
1143 self.assertHelp(parser, expected_help)
1144
1145
1146class TestCallbackExtraArgs(BaseTest):
Greg Ward55493222003-04-21 02:41:25 +00001147 def setUp(self):
1148 options = [make_option("-p", "--point", action="callback",
1149 callback=self.process_tuple,
1150 callback_args=(3, int), type="string",
1151 dest="points", default=[])]
1152 self.parser = OptionParser(option_list=options)
1153
Greg Wardab05edc2006-04-23 03:47:58 +00001154 def process_tuple(self, option, opt, value, parser_, len, type):
Greg Ward55493222003-04-21 02:41:25 +00001155 self.assertEqual(len, 3)
Benjamin Peterson5c8da862009-06-30 22:57:08 +00001156 self.assertTrue(type is int)
Greg Ward55493222003-04-21 02:41:25 +00001157
1158 if opt == "-p":
1159 self.assertEqual(value, "1,2,3")
1160 elif opt == "--point":
1161 self.assertEqual(value, "4,5,6")
1162
1163 value = tuple(map(type, value.split(",")))
1164 getattr(parser_.values, option.dest).append(value)
1165
1166 def test_callback_extra_args(self):
1167 self.assertParseOK(["-p1,2,3", "--point", "4,5,6"],
1168 {'points': [(1,2,3), (4,5,6)]},
1169 [])
1170
Greg Wardeba20e62004-07-31 16:15:44 +00001171class TestCallbackMeddleArgs(BaseTest):
Greg Ward55493222003-04-21 02:41:25 +00001172 def setUp(self):
1173 options = [make_option(str(x), action="callback",
1174 callback=self.process_n, dest='things')
1175 for x in range(-1, -6, -1)]
1176 self.parser = OptionParser(option_list=options)
1177
1178 # Callback that meddles in rargs, largs
Greg Wardab05edc2006-04-23 03:47:58 +00001179 def process_n(self, option, opt, value, parser_):
Greg Ward55493222003-04-21 02:41:25 +00001180 # option is -3, -5, etc.
1181 nargs = int(opt[1:])
1182 rargs = parser_.rargs
1183 if len(rargs) < nargs:
1184 self.fail("Expected %d arguments for %s option." % (nargs, opt))
1185 dest = parser_.values.ensure_value(option.dest, [])
1186 dest.append(tuple(rargs[0:nargs]))
1187 parser_.largs.append(nargs)
1188 del rargs[0:nargs]
1189
1190 def test_callback_meddle_args(self):
1191 self.assertParseOK(["-1", "foo", "-3", "bar", "baz", "qux"],
1192 {'things': [("foo",), ("bar", "baz", "qux")]},
1193 [1, 3])
1194
1195 def test_callback_meddle_args_separator(self):
1196 self.assertParseOK(["-2", "foo", "--"],
1197 {'things': [('foo', '--')]},
1198 [2])
1199
Greg Wardeba20e62004-07-31 16:15:44 +00001200class TestCallbackManyArgs(BaseTest):
Greg Ward55493222003-04-21 02:41:25 +00001201 def setUp(self):
1202 options = [make_option("-a", "--apple", action="callback", nargs=2,
1203 callback=self.process_many, type="string"),
1204 make_option("-b", "--bob", action="callback", nargs=3,
1205 callback=self.process_many, type="int")]
1206 self.parser = OptionParser(option_list=options)
1207
Greg Wardab05edc2006-04-23 03:47:58 +00001208 def process_many(self, option, opt, value, parser_):
Greg Ward55493222003-04-21 02:41:25 +00001209 if opt == "-a":
1210 self.assertEqual(value, ("foo", "bar"))
1211 elif opt == "--apple":
1212 self.assertEqual(value, ("ding", "dong"))
1213 elif opt == "-b":
1214 self.assertEqual(value, (1, 2, 3))
1215 elif opt == "--bob":
1216 self.assertEqual(value, (-666, 42, 0))
1217
1218 def test_many_args(self):
1219 self.assertParseOK(["-a", "foo", "bar", "--apple", "ding", "dong",
1220 "-b", "1", "2", "3", "--bob", "-666", "42",
1221 "0"],
Greg Wardeba20e62004-07-31 16:15:44 +00001222 {"apple": None, "bob": None},
Greg Ward55493222003-04-21 02:41:25 +00001223 [])
1224
Greg Wardeba20e62004-07-31 16:15:44 +00001225class TestCallbackCheckAbbrev(BaseTest):
Greg Ward55493222003-04-21 02:41:25 +00001226 def setUp(self):
1227 self.parser = OptionParser()
1228 self.parser.add_option("--foo-bar", action="callback",
1229 callback=self.check_abbrev)
1230
Greg Wardab05edc2006-04-23 03:47:58 +00001231 def check_abbrev(self, option, opt, value, parser):
Greg Ward55493222003-04-21 02:41:25 +00001232 self.assertEqual(opt, "--foo-bar")
1233
1234 def test_abbrev_callback_expansion(self):
1235 self.assertParseOK(["--foo"], {}, [])
1236
Greg Wardeba20e62004-07-31 16:15:44 +00001237class TestCallbackVarArgs(BaseTest):
Greg Ward55493222003-04-21 02:41:25 +00001238 def setUp(self):
1239 options = [make_option("-a", type="int", nargs=2, dest="a"),
1240 make_option("-b", action="store_true", dest="b"),
1241 make_option("-c", "--callback", action="callback",
1242 callback=self.variable_args, dest="c")]
Greg Ward48aa84b2004-10-27 02:20:04 +00001243 self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE,
1244 option_list=options)
Greg Ward55493222003-04-21 02:41:25 +00001245
Greg Wardab05edc2006-04-23 03:47:58 +00001246 def variable_args(self, option, opt, value, parser):
Benjamin Peterson5c8da862009-06-30 22:57:08 +00001247 self.assertTrue(value is None)
Greg Ward55493222003-04-21 02:41:25 +00001248 value = []
1249 rargs = parser.rargs
1250 while rargs:
1251 arg = rargs[0]
1252 if ((arg[:2] == "--" and len(arg) > 2) or
1253 (arg[:1] == "-" and len(arg) > 1 and arg[1] != "-")):
1254 break
1255 else:
1256 value.append(arg)
1257 del rargs[0]
1258 setattr(parser.values, option.dest, value)
1259
1260 def test_variable_args(self):
1261 self.assertParseOK(["-a3", "-5", "--callback", "foo", "bar"],
1262 {'a': (3, -5), 'b': None, 'c': ["foo", "bar"]},
1263 [])
1264
1265 def test_consume_separator_stop_at_option(self):
1266 self.assertParseOK(["-c", "37", "--", "xxx", "-b", "hello"],
1267 {'a': None,
1268 'b': True,
1269 'c': ["37", "--", "xxx"]},
1270 ["hello"])
1271
1272 def test_positional_arg_and_variable_args(self):
1273 self.assertParseOK(["hello", "-c", "foo", "-", "bar"],
1274 {'a': None,
1275 'b': None,
1276 'c':["foo", "-", "bar"]},
1277 ["hello"])
1278
1279 def test_stop_at_option(self):
1280 self.assertParseOK(["-c", "foo", "-b"],
1281 {'a': None, 'b': True, 'c': ["foo"]},
1282 [])
1283
1284 def test_stop_at_invalid_option(self):
1285 self.assertParseFail(["-c", "3", "-5", "-a"], "no such option: -5")
1286
1287
1288# -- Test conflict handling and parser.parse_args() --------------------
1289
1290class ConflictBase(BaseTest):
1291 def setUp(self):
1292 options = [make_option("-v", "--verbose", action="count",
1293 dest="verbose", help="increment verbosity")]
Greg Ward48aa84b2004-10-27 02:20:04 +00001294 self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE,
1295 option_list=options)
Greg Ward55493222003-04-21 02:41:25 +00001296
Greg Wardab05edc2006-04-23 03:47:58 +00001297 def show_version(self, option, opt, value, parser):
Greg Ward55493222003-04-21 02:41:25 +00001298 parser.values.show_version = 1
1299
1300class TestConflict(ConflictBase):
1301 """Use the default conflict resolution for Optik 1.2: error."""
Benjamin Peterson5c8da862009-06-30 22:57:08 +00001302 def assertTrueconflict_error(self, func):
Greg Wardeba20e62004-07-31 16:15:44 +00001303 err = self.assertRaises(
1304 func, ("-v", "--version"), {'action' : "callback",
1305 'callback' : self.show_version,
1306 'help' : "show version"},
1307 OptionConflictError,
1308 "option -v/--version: conflicting option string(s): -v")
Greg Ward55493222003-04-21 02:41:25 +00001309
1310 self.assertEqual(err.msg, "conflicting option string(s): -v")
1311 self.assertEqual(err.option_id, "-v/--version")
1312
1313 def test_conflict_error(self):
Benjamin Peterson5c8da862009-06-30 22:57:08 +00001314 self.assertTrueconflict_error(self.parser.add_option)
Greg Ward55493222003-04-21 02:41:25 +00001315
1316 def test_conflict_error_group(self):
1317 group = OptionGroup(self.parser, "Group 1")
Benjamin Peterson5c8da862009-06-30 22:57:08 +00001318 self.assertTrueconflict_error(group.add_option)
Greg Ward55493222003-04-21 02:41:25 +00001319
1320 def test_no_such_conflict_handler(self):
Greg Wardeba20e62004-07-31 16:15:44 +00001321 self.assertRaises(
1322 self.parser.set_conflict_handler, ('foo',), None,
1323 ValueError, "invalid conflict_resolution value 'foo'")
Greg Ward55493222003-04-21 02:41:25 +00001324
1325
Greg Ward55493222003-04-21 02:41:25 +00001326class TestConflictResolve(ConflictBase):
1327 def setUp(self):
1328 ConflictBase.setUp(self)
1329 self.parser.set_conflict_handler("resolve")
1330 self.parser.add_option("-v", "--version", action="callback",
1331 callback=self.show_version, help="show version")
1332
1333 def test_conflict_resolve(self):
1334 v_opt = self.parser.get_option("-v")
1335 verbose_opt = self.parser.get_option("--verbose")
1336 version_opt = self.parser.get_option("--version")
1337
Benjamin Peterson5c8da862009-06-30 22:57:08 +00001338 self.assertTrue(v_opt is version_opt)
1339 self.assertTrue(v_opt is not verbose_opt)
Greg Ward55493222003-04-21 02:41:25 +00001340 self.assertEqual(v_opt._long_opts, ["--version"])
1341 self.assertEqual(version_opt._short_opts, ["-v"])
1342 self.assertEqual(version_opt._long_opts, ["--version"])
1343 self.assertEqual(verbose_opt._short_opts, [])
1344 self.assertEqual(verbose_opt._long_opts, ["--verbose"])
1345
1346 def test_conflict_resolve_help(self):
Greg Ward48aa84b2004-10-27 02:20:04 +00001347 self.assertOutput(["-h"], """\
Greg Wardab05edc2006-04-23 03:47:58 +00001348Options:
Greg Ward55493222003-04-21 02:41:25 +00001349 --verbose increment verbosity
1350 -h, --help show this help message and exit
1351 -v, --version show version
1352""")
1353
1354 def test_conflict_resolve_short_opt(self):
1355 self.assertParseOK(["-v"],
1356 {'verbose': None, 'show_version': 1},
1357 [])
1358
1359 def test_conflict_resolve_long_opt(self):
1360 self.assertParseOK(["--verbose"],
1361 {'verbose': 1},
1362 [])
1363
1364 def test_conflict_resolve_long_opts(self):
1365 self.assertParseOK(["--verbose", "--version"],
1366 {'verbose': 1, 'show_version': 1},
1367 [])
1368
1369class TestConflictOverride(BaseTest):
1370 def setUp(self):
Greg Ward48aa84b2004-10-27 02:20:04 +00001371 self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE)
Greg Ward55493222003-04-21 02:41:25 +00001372 self.parser.set_conflict_handler("resolve")
1373 self.parser.add_option("-n", "--dry-run",
1374 action="store_true", dest="dry_run",
1375 help="don't do anything")
1376 self.parser.add_option("--dry-run", "-n",
1377 action="store_const", const=42, dest="dry_run",
1378 help="dry run mode")
1379
1380 def test_conflict_override_opts(self):
1381 opt = self.parser.get_option("--dry-run")
1382 self.assertEqual(opt._short_opts, ["-n"])
1383 self.assertEqual(opt._long_opts, ["--dry-run"])
1384
1385 def test_conflict_override_help(self):
Greg Ward48aa84b2004-10-27 02:20:04 +00001386 self.assertOutput(["-h"], """\
Greg Wardab05edc2006-04-23 03:47:58 +00001387Options:
Greg Ward55493222003-04-21 02:41:25 +00001388 -h, --help show this help message and exit
1389 -n, --dry-run dry run mode
1390""")
1391
1392 def test_conflict_override_args(self):
1393 self.assertParseOK(["-n"],
1394 {'dry_run': 42},
1395 [])
1396
1397# -- Other testing. ----------------------------------------------------
1398
Greg Wardeba20e62004-07-31 16:15:44 +00001399_expected_help_basic = """\
Greg Wardab05edc2006-04-23 03:47:58 +00001400Usage: bar.py [options]
Greg Wardeba20e62004-07-31 16:15:44 +00001401
Greg Wardab05edc2006-04-23 03:47:58 +00001402Options:
Greg Wardeba20e62004-07-31 16:15:44 +00001403 -a APPLE throw APPLEs at basket
1404 -b NUM, --boo=NUM shout "boo!" NUM times (in order to frighten away all the
1405 evil spirits that cause trouble and mayhem)
1406 --foo=FOO store FOO in the foo list for later fooing
1407 -h, --help show this help message and exit
1408"""
1409
1410_expected_help_long_opts_first = """\
Greg Wardab05edc2006-04-23 03:47:58 +00001411Usage: bar.py [options]
Greg Wardeba20e62004-07-31 16:15:44 +00001412
Greg Wardab05edc2006-04-23 03:47:58 +00001413Options:
Greg Wardeba20e62004-07-31 16:15:44 +00001414 -a APPLE throw APPLEs at basket
1415 --boo=NUM, -b NUM shout "boo!" NUM times (in order to frighten away all the
1416 evil spirits that cause trouble and mayhem)
1417 --foo=FOO store FOO in the foo list for later fooing
1418 --help, -h show this help message and exit
1419"""
1420
1421_expected_help_title_formatter = """\
1422Usage
1423=====
1424 bar.py [options]
1425
Greg Wardab05edc2006-04-23 03:47:58 +00001426Options
Greg Wardeba20e62004-07-31 16:15:44 +00001427=======
1428-a APPLE throw APPLEs at basket
1429--boo=NUM, -b NUM shout "boo!" NUM times (in order to frighten away all the
1430 evil spirits that cause trouble and mayhem)
1431--foo=FOO store FOO in the foo list for later fooing
1432--help, -h show this help message and exit
1433"""
1434
1435_expected_help_short_lines = """\
Greg Wardab05edc2006-04-23 03:47:58 +00001436Usage: bar.py [options]
Greg Wardeba20e62004-07-31 16:15:44 +00001437
Greg Wardab05edc2006-04-23 03:47:58 +00001438Options:
Greg Wardeba20e62004-07-31 16:15:44 +00001439 -a APPLE throw APPLEs at basket
1440 -b NUM, --boo=NUM shout "boo!" NUM times (in order to
1441 frighten away all the evil spirits
1442 that cause trouble and mayhem)
1443 --foo=FOO store FOO in the foo list for later
1444 fooing
1445 -h, --help show this help message and exit
1446"""
1447
Serhiy Storchaka9f8621f2014-01-09 23:13:48 +02001448_expected_very_help_short_lines = """\
1449Usage: bar.py [options]
1450
1451Options:
1452 -a APPLE
1453 throw
1454 APPLEs at
1455 basket
1456 -b NUM, --boo=NUM
1457 shout
1458 "boo!" NUM
1459 times (in
1460 order to
1461 frighten
1462 away all
1463 the evil
1464 spirits
1465 that cause
1466 trouble and
1467 mayhem)
1468 --foo=FOO
1469 store FOO
1470 in the foo
1471 list for
1472 later
1473 fooing
1474 -h, --help
1475 show this
1476 help
1477 message and
1478 exit
1479"""
1480
Greg Ward55493222003-04-21 02:41:25 +00001481class TestHelp(BaseTest):
1482 def setUp(self):
Greg Wardeba20e62004-07-31 16:15:44 +00001483 self.parser = self.make_parser(80)
1484
1485 def make_parser(self, columns):
Greg Ward55493222003-04-21 02:41:25 +00001486 options = [
1487 make_option("-a", type="string", dest='a',
1488 metavar="APPLE", help="throw APPLEs at basket"),
1489 make_option("-b", "--boo", type="int", dest='boo',
1490 metavar="NUM",
1491 help=
1492 "shout \"boo!\" NUM times (in order to frighten away "
1493 "all the evil spirits that cause trouble and mayhem)"),
1494 make_option("--foo", action="append", type="string", dest='foo',
1495 help="store FOO in the foo list for later fooing"),
1496 ]
Greg Ward48fae7a2006-07-23 16:05:51 +00001497
1498 # We need to set COLUMNS for the OptionParser constructor, but
1499 # we must restore its original value -- otherwise, this test
1500 # screws things up for other tests when it's part of the Python
1501 # test suite.
Walter Dörwald4b965f62009-04-26 20:51:44 +00001502 with test_support.EnvironmentVarGuard() as env:
Walter Dörwald6733bed2009-05-01 17:35:37 +00001503 env['COLUMNS'] = str(columns)
Tim Peterse7d7caa2006-06-19 09:09:44 +00001504 return InterceptingOptionParser(option_list=options)
Greg Ward55493222003-04-21 02:41:25 +00001505
1506 def assertHelpEquals(self, expected_output):
Greg Ward0e0c9f42006-06-11 16:24:11 +00001507 if type(expected_output) is types.UnicodeType:
1508 encoding = self.parser._get_encoding(sys.stdout)
1509 expected_output = expected_output.encode(encoding, "replace")
1510
Greg Ward48aa84b2004-10-27 02:20:04 +00001511 save_argv = sys.argv[:]
1512 try:
1513 # Make optparse believe bar.py is being executed.
1514 sys.argv[0] = os.path.join("foo", "bar.py")
1515 self.assertOutput(["-h"], expected_output)
1516 finally:
1517 sys.argv[:] = save_argv
Greg Ward55493222003-04-21 02:41:25 +00001518
1519 def test_help(self):
Greg Wardeba20e62004-07-31 16:15:44 +00001520 self.assertHelpEquals(_expected_help_basic)
Greg Ward55493222003-04-21 02:41:25 +00001521
1522 def test_help_old_usage(self):
Greg Wardab05edc2006-04-23 03:47:58 +00001523 self.parser.set_usage("Usage: %prog [options]")
Greg Wardeba20e62004-07-31 16:15:44 +00001524 self.assertHelpEquals(_expected_help_basic)
Greg Ward55493222003-04-21 02:41:25 +00001525
1526 def test_help_long_opts_first(self):
1527 self.parser.formatter.short_first = 0
Greg Wardeba20e62004-07-31 16:15:44 +00001528 self.assertHelpEquals(_expected_help_long_opts_first)
Greg Ward55493222003-04-21 02:41:25 +00001529
1530 def test_help_title_formatter(self):
Walter Dörwald4b965f62009-04-26 20:51:44 +00001531 with test_support.EnvironmentVarGuard() as env:
Walter Dörwald6733bed2009-05-01 17:35:37 +00001532 env["COLUMNS"] = "80"
Guido van Rossum0567ba22007-01-14 03:46:33 +00001533 self.parser.formatter = TitledHelpFormatter()
1534 self.assertHelpEquals(_expected_help_title_formatter)
Greg Ward55493222003-04-21 02:41:25 +00001535
Greg Wardeba20e62004-07-31 16:15:44 +00001536 def test_wrap_columns(self):
1537 # Ensure that wrapping respects $COLUMNS environment variable.
1538 # Need to reconstruct the parser, since that's the only time
1539 # we look at $COLUMNS.
1540 self.parser = self.make_parser(60)
1541 self.assertHelpEquals(_expected_help_short_lines)
Serhiy Storchaka9f8621f2014-01-09 23:13:48 +02001542 self.parser = self.make_parser(0)
1543 self.assertHelpEquals(_expected_very_help_short_lines)
Greg Ward55493222003-04-21 02:41:25 +00001544
Greg Ward0e0c9f42006-06-11 16:24:11 +00001545 def test_help_unicode(self):
1546 self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE)
1547 self.parser.add_option("-a", action="store_true", help=u"ol\u00E9!")
1548 expect = u"""\
1549Options:
1550 -h, --help show this help message and exit
1551 -a ol\u00E9!
1552"""
1553 self.assertHelpEquals(expect)
1554
1555 def test_help_unicode_description(self):
1556 self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE,
1557 description=u"ol\u00E9!")
1558 expect = u"""\
1559ol\u00E9!
1560
1561Options:
1562 -h, --help show this help message and exit
1563"""
1564 self.assertHelpEquals(expect)
1565
Greg Ward55493222003-04-21 02:41:25 +00001566 def test_help_description_groups(self):
1567 self.parser.set_description(
Greg Wardeba20e62004-07-31 16:15:44 +00001568 "This is the program description for %prog. %prog has "
Greg Ward55493222003-04-21 02:41:25 +00001569 "an option group as well as single options.")
1570
1571 group = OptionGroup(
1572 self.parser, "Dangerous Options",
1573 "Caution: use of these options is at your own risk. "
1574 "It is believed that some of them bite.")
1575 group.add_option("-g", action="store_true", help="Group option.")
1576 self.parser.add_option_group(group)
1577
Greg Wardab05edc2006-04-23 03:47:58 +00001578 expect = """\
1579Usage: bar.py [options]
Greg Ward55493222003-04-21 02:41:25 +00001580
Greg Wardeba20e62004-07-31 16:15:44 +00001581This is the program description for bar.py. bar.py has an option group as
1582well as single options.
1583
Greg Wardab05edc2006-04-23 03:47:58 +00001584Options:
Greg Wardeba20e62004-07-31 16:15:44 +00001585 -a APPLE throw APPLEs at basket
1586 -b NUM, --boo=NUM shout "boo!" NUM times (in order to frighten away all the
1587 evil spirits that cause trouble and mayhem)
1588 --foo=FOO store FOO in the foo list for later fooing
1589 -h, --help show this help message and exit
Greg Ward55493222003-04-21 02:41:25 +00001590
1591 Dangerous Options:
Greg Wardeba20e62004-07-31 16:15:44 +00001592 Caution: use of these options is at your own risk. It is believed
1593 that some of them bite.
1594
1595 -g Group option.
Greg Wardab05edc2006-04-23 03:47:58 +00001596"""
Greg Ward55493222003-04-21 02:41:25 +00001597
Greg Wardab05edc2006-04-23 03:47:58 +00001598 self.assertHelpEquals(expect)
Greg Wardeba20e62004-07-31 16:15:44 +00001599
Greg Wardab05edc2006-04-23 03:47:58 +00001600 self.parser.epilog = "Please report bugs to /dev/null."
1601 self.assertHelpEquals(expect + "\nPlease report bugs to /dev/null.\n")
Tim Peters10d59f32004-10-27 02:43:25 +00001602
Greg Wardeba20e62004-07-31 16:15:44 +00001603
Greg Ward55493222003-04-21 02:41:25 +00001604class TestMatchAbbrev(BaseTest):
1605 def test_match_abbrev(self):
1606 self.assertEqual(_match_abbrev("--f",
1607 {"--foz": None,
1608 "--foo": None,
1609 "--fie": None,
1610 "--f": None}),
1611 "--f")
1612
1613 def test_match_abbrev_error(self):
1614 s = "--f"
1615 wordmap = {"--foz": None, "--foo": None, "--fie": None}
Greg Wardeba20e62004-07-31 16:15:44 +00001616 self.assertRaises(
1617 _match_abbrev, (s, wordmap), None,
Armin Rigoa3f09272006-05-28 19:13:17 +00001618 BadOptionError, "ambiguous option: --f (--fie, --foo, --foz?)")
Greg Wardeba20e62004-07-31 16:15:44 +00001619
1620
Greg Wardab05edc2006-04-23 03:47:58 +00001621class TestParseNumber(BaseTest):
1622 def setUp(self):
1623 self.parser = InterceptingOptionParser()
1624 self.parser.add_option("-n", type=int)
1625 self.parser.add_option("-l", type=long)
1626
1627 def test_parse_num_fail(self):
1628 self.assertRaises(
1629 _parse_num, ("", int), {},
1630 ValueError,
1631 re.compile(r"invalid literal for int().*: '?'?"))
1632 self.assertRaises(
1633 _parse_num, ("0xOoops", long), {},
1634 ValueError,
1635 re.compile(r"invalid literal for long().*: '?0xOoops'?"))
1636
1637 def test_parse_num_ok(self):
1638 self.assertEqual(_parse_num("0", int), 0)
1639 self.assertEqual(_parse_num("0x10", int), 16)
1640 self.assertEqual(_parse_num("0XA", long), 10L)
1641 self.assertEqual(_parse_num("010", long), 8L)
1642 self.assertEqual(_parse_num("0b11", int), 3)
1643 self.assertEqual(_parse_num("0b", long), 0L)
1644
1645 def test_numeric_options(self):
1646 self.assertParseOK(["-n", "42", "-l", "0x20"],
1647 { "n": 42, "l": 0x20 }, [])
1648 self.assertParseOK(["-n", "0b0101", "-l010"],
1649 { "n": 5, "l": 8 }, [])
1650 self.assertParseFail(["-n008"],
1651 "option -n: invalid integer value: '008'")
1652 self.assertParseFail(["-l0b0123"],
1653 "option -l: invalid long integer value: '0b0123'")
1654 self.assertParseFail(["-l", "0x12x"],
1655 "option -l: invalid long integer value: '0x12x'")
1656
1657
Greg Ward55493222003-04-21 02:41:25 +00001658def test_main():
Collin Winterc2898c52007-04-25 17:29:52 +00001659 test_support.run_unittest(__name__)
Greg Ward55493222003-04-21 02:41:25 +00001660
1661if __name__ == '__main__':
Collin Winterc2898c52007-04-25 17:29:52 +00001662 test_main()