ยปCore Development>Code coverage>Lib/test/test_argparse.py

Python code coverage for Lib/test/test_argparse.py

#countcontent
1n/a# Author: Steven J. Bethard <steven.bethard@gmail.com>.
2n/a
3n/aimport codecs
4n/aimport inspect
5n/aimport os
6n/aimport shutil
7n/aimport stat
8n/aimport sys
9n/aimport textwrap
10n/aimport tempfile
11n/aimport unittest
12n/aimport argparse
13n/a
14n/afrom io import StringIO
15n/a
16n/afrom test import support
17n/afrom unittest import mock
18n/aclass StdIOBuffer(StringIO):
19n/a pass
20n/a
21n/aclass TestCase(unittest.TestCase):
22n/a
23n/a def setUp(self):
24n/a # The tests assume that line wrapping occurs at 80 columns, but this
25n/a # behaviour can be overridden by setting the COLUMNS environment
26n/a # variable. To ensure that this assumption is true, unset COLUMNS.
27n/a env = support.EnvironmentVarGuard()
28n/a env.unset("COLUMNS")
29n/a self.addCleanup(env.__exit__)
30n/a
31n/a
32n/aclass TempDirMixin(object):
33n/a
34n/a def setUp(self):
35n/a self.temp_dir = tempfile.mkdtemp()
36n/a self.old_dir = os.getcwd()
37n/a os.chdir(self.temp_dir)
38n/a
39n/a def tearDown(self):
40n/a os.chdir(self.old_dir)
41n/a for root, dirs, files in os.walk(self.temp_dir, topdown=False):
42n/a for name in files:
43n/a os.chmod(os.path.join(self.temp_dir, name), stat.S_IWRITE)
44n/a shutil.rmtree(self.temp_dir, True)
45n/a
46n/a def create_readonly_file(self, filename):
47n/a file_path = os.path.join(self.temp_dir, filename)
48n/a with open(file_path, 'w') as file:
49n/a file.write(filename)
50n/a os.chmod(file_path, stat.S_IREAD)
51n/a
52n/aclass Sig(object):
53n/a
54n/a def __init__(self, *args, **kwargs):
55n/a self.args = args
56n/a self.kwargs = kwargs
57n/a
58n/a
59n/aclass NS(object):
60n/a
61n/a def __init__(self, **kwargs):
62n/a self.__dict__.update(kwargs)
63n/a
64n/a def __repr__(self):
65n/a sorted_items = sorted(self.__dict__.items())
66n/a kwarg_str = ', '.join(['%s=%r' % tup for tup in sorted_items])
67n/a return '%s(%s)' % (type(self).__name__, kwarg_str)
68n/a
69n/a def __eq__(self, other):
70n/a return vars(self) == vars(other)
71n/a
72n/a
73n/aclass ArgumentParserError(Exception):
74n/a
75n/a def __init__(self, message, stdout=None, stderr=None, error_code=None):
76n/a Exception.__init__(self, message, stdout, stderr)
77n/a self.message = message
78n/a self.stdout = stdout
79n/a self.stderr = stderr
80n/a self.error_code = error_code
81n/a
82n/a
83n/adef stderr_to_parser_error(parse_args, *args, **kwargs):
84n/a # if this is being called recursively and stderr or stdout is already being
85n/a # redirected, simply call the function and let the enclosing function
86n/a # catch the exception
87n/a if isinstance(sys.stderr, StdIOBuffer) or isinstance(sys.stdout, StdIOBuffer):
88n/a return parse_args(*args, **kwargs)
89n/a
90n/a # if this is not being called recursively, redirect stderr and
91n/a # use it as the ArgumentParserError message
92n/a old_stdout = sys.stdout
93n/a old_stderr = sys.stderr
94n/a sys.stdout = StdIOBuffer()
95n/a sys.stderr = StdIOBuffer()
96n/a try:
97n/a try:
98n/a result = parse_args(*args, **kwargs)
99n/a for key in list(vars(result)):
100n/a if getattr(result, key) is sys.stdout:
101n/a setattr(result, key, old_stdout)
102n/a if getattr(result, key) is sys.stderr:
103n/a setattr(result, key, old_stderr)
104n/a return result
105n/a except SystemExit:
106n/a code = sys.exc_info()[1].code
107n/a stdout = sys.stdout.getvalue()
108n/a stderr = sys.stderr.getvalue()
109n/a raise ArgumentParserError("SystemExit", stdout, stderr, code)
110n/a finally:
111n/a sys.stdout = old_stdout
112n/a sys.stderr = old_stderr
113n/a
114n/a
115n/aclass ErrorRaisingArgumentParser(argparse.ArgumentParser):
116n/a
117n/a def parse_args(self, *args, **kwargs):
118n/a parse_args = super(ErrorRaisingArgumentParser, self).parse_args
119n/a return stderr_to_parser_error(parse_args, *args, **kwargs)
120n/a
121n/a def exit(self, *args, **kwargs):
122n/a exit = super(ErrorRaisingArgumentParser, self).exit
123n/a return stderr_to_parser_error(exit, *args, **kwargs)
124n/a
125n/a def error(self, *args, **kwargs):
126n/a error = super(ErrorRaisingArgumentParser, self).error
127n/a return stderr_to_parser_error(error, *args, **kwargs)
128n/a
129n/a
130n/aclass ParserTesterMetaclass(type):
131n/a """Adds parser tests using the class attributes.
132n/a
133n/a Classes of this type should specify the following attributes:
134n/a
135n/a argument_signatures -- a list of Sig objects which specify
136n/a the signatures of Argument objects to be created
137n/a failures -- a list of args lists that should cause the parser
138n/a to fail
139n/a successes -- a list of (initial_args, options, remaining_args) tuples
140n/a where initial_args specifies the string args to be parsed,
141n/a options is a dict that should match the vars() of the options
142n/a parsed out of initial_args, and remaining_args should be any
143n/a remaining unparsed arguments
144n/a """
145n/a
146n/a def __init__(cls, name, bases, bodydict):
147n/a if name == 'ParserTestCase':
148n/a return
149n/a
150n/a # default parser signature is empty
151n/a if not hasattr(cls, 'parser_signature'):
152n/a cls.parser_signature = Sig()
153n/a if not hasattr(cls, 'parser_class'):
154n/a cls.parser_class = ErrorRaisingArgumentParser
155n/a
156n/a # ---------------------------------------
157n/a # functions for adding optional arguments
158n/a # ---------------------------------------
159n/a def no_groups(parser, argument_signatures):
160n/a """Add all arguments directly to the parser"""
161n/a for sig in argument_signatures:
162n/a parser.add_argument(*sig.args, **sig.kwargs)
163n/a
164n/a def one_group(parser, argument_signatures):
165n/a """Add all arguments under a single group in the parser"""
166n/a group = parser.add_argument_group('foo')
167n/a for sig in argument_signatures:
168n/a group.add_argument(*sig.args, **sig.kwargs)
169n/a
170n/a def many_groups(parser, argument_signatures):
171n/a """Add each argument in its own group to the parser"""
172n/a for i, sig in enumerate(argument_signatures):
173n/a group = parser.add_argument_group('foo:%i' % i)
174n/a group.add_argument(*sig.args, **sig.kwargs)
175n/a
176n/a # --------------------------
177n/a # functions for parsing args
178n/a # --------------------------
179n/a def listargs(parser, args):
180n/a """Parse the args by passing in a list"""
181n/a return parser.parse_args(args)
182n/a
183n/a def sysargs(parser, args):
184n/a """Parse the args by defaulting to sys.argv"""
185n/a old_sys_argv = sys.argv
186n/a sys.argv = [old_sys_argv[0]] + args
187n/a try:
188n/a return parser.parse_args()
189n/a finally:
190n/a sys.argv = old_sys_argv
191n/a
192n/a # class that holds the combination of one optional argument
193n/a # addition method and one arg parsing method
194n/a class AddTests(object):
195n/a
196n/a def __init__(self, tester_cls, add_arguments, parse_args):
197n/a self._add_arguments = add_arguments
198n/a self._parse_args = parse_args
199n/a
200n/a add_arguments_name = self._add_arguments.__name__
201n/a parse_args_name = self._parse_args.__name__
202n/a for test_func in [self.test_failures, self.test_successes]:
203n/a func_name = test_func.__name__
204n/a names = func_name, add_arguments_name, parse_args_name
205n/a test_name = '_'.join(names)
206n/a
207n/a def wrapper(self, test_func=test_func):
208n/a test_func(self)
209n/a try:
210n/a wrapper.__name__ = test_name
211n/a except TypeError:
212n/a pass
213n/a setattr(tester_cls, test_name, wrapper)
214n/a
215n/a def _get_parser(self, tester):
216n/a args = tester.parser_signature.args
217n/a kwargs = tester.parser_signature.kwargs
218n/a parser = tester.parser_class(*args, **kwargs)
219n/a self._add_arguments(parser, tester.argument_signatures)
220n/a return parser
221n/a
222n/a def test_failures(self, tester):
223n/a parser = self._get_parser(tester)
224n/a for args_str in tester.failures:
225n/a args = args_str.split()
226n/a with tester.assertRaises(ArgumentParserError, msg=args):
227n/a parser.parse_args(args)
228n/a
229n/a def test_successes(self, tester):
230n/a parser = self._get_parser(tester)
231n/a for args, expected_ns in tester.successes:
232n/a if isinstance(args, str):
233n/a args = args.split()
234n/a result_ns = self._parse_args(parser, args)
235n/a tester.assertEqual(expected_ns, result_ns)
236n/a
237n/a # add tests for each combination of an optionals adding method
238n/a # and an arg parsing method
239n/a for add_arguments in [no_groups, one_group, many_groups]:
240n/a for parse_args in [listargs, sysargs]:
241n/a AddTests(cls, add_arguments, parse_args)
242n/a
243n/abases = TestCase,
244n/aParserTestCase = ParserTesterMetaclass('ParserTestCase', bases, {})
245n/a
246n/a# ===============
247n/a# Optionals tests
248n/a# ===============
249n/a
250n/aclass TestOptionalsSingleDash(ParserTestCase):
251n/a """Test an Optional with a single-dash option string"""
252n/a
253n/a argument_signatures = [Sig('-x')]
254n/a failures = ['-x', 'a', '--foo', '-x --foo', '-x -y']
255n/a successes = [
256n/a ('', NS(x=None)),
257n/a ('-x a', NS(x='a')),
258n/a ('-xa', NS(x='a')),
259n/a ('-x -1', NS(x='-1')),
260n/a ('-x-1', NS(x='-1')),
261n/a ]
262n/a
263n/a
264n/aclass TestOptionalsSingleDashCombined(ParserTestCase):
265n/a """Test an Optional with a single-dash option string"""
266n/a
267n/a argument_signatures = [
268n/a Sig('-x', action='store_true'),
269n/a Sig('-yyy', action='store_const', const=42),
270n/a Sig('-z'),
271n/a ]
272n/a failures = ['a', '--foo', '-xa', '-x --foo', '-x -z', '-z -x',
273n/a '-yx', '-yz a', '-yyyx', '-yyyza', '-xyza']
274n/a successes = [
275n/a ('', NS(x=False, yyy=None, z=None)),
276n/a ('-x', NS(x=True, yyy=None, z=None)),
277n/a ('-za', NS(x=False, yyy=None, z='a')),
278n/a ('-z a', NS(x=False, yyy=None, z='a')),
279n/a ('-xza', NS(x=True, yyy=None, z='a')),
280n/a ('-xz a', NS(x=True, yyy=None, z='a')),
281n/a ('-x -za', NS(x=True, yyy=None, z='a')),
282n/a ('-x -z a', NS(x=True, yyy=None, z='a')),
283n/a ('-y', NS(x=False, yyy=42, z=None)),
284n/a ('-yyy', NS(x=False, yyy=42, z=None)),
285n/a ('-x -yyy -za', NS(x=True, yyy=42, z='a')),
286n/a ('-x -yyy -z a', NS(x=True, yyy=42, z='a')),
287n/a ]
288n/a
289n/a
290n/aclass TestOptionalsSingleDashLong(ParserTestCase):
291n/a """Test an Optional with a multi-character single-dash option string"""
292n/a
293n/a argument_signatures = [Sig('-foo')]
294n/a failures = ['-foo', 'a', '--foo', '-foo --foo', '-foo -y', '-fooa']
295n/a successes = [
296n/a ('', NS(foo=None)),
297n/a ('-foo a', NS(foo='a')),
298n/a ('-foo -1', NS(foo='-1')),
299n/a ('-fo a', NS(foo='a')),
300n/a ('-f a', NS(foo='a')),
301n/a ]
302n/a
303n/a
304n/aclass TestOptionalsSingleDashSubsetAmbiguous(ParserTestCase):
305n/a """Test Optionals where option strings are subsets of each other"""
306n/a
307n/a argument_signatures = [Sig('-f'), Sig('-foobar'), Sig('-foorab')]
308n/a failures = ['-f', '-foo', '-fo', '-foo b', '-foob', '-fooba', '-foora']
309n/a successes = [
310n/a ('', NS(f=None, foobar=None, foorab=None)),
311n/a ('-f a', NS(f='a', foobar=None, foorab=None)),
312n/a ('-fa', NS(f='a', foobar=None, foorab=None)),
313n/a ('-foa', NS(f='oa', foobar=None, foorab=None)),
314n/a ('-fooa', NS(f='ooa', foobar=None, foorab=None)),
315n/a ('-foobar a', NS(f=None, foobar='a', foorab=None)),
316n/a ('-foorab a', NS(f=None, foobar=None, foorab='a')),
317n/a ]
318n/a
319n/a
320n/aclass TestOptionalsSingleDashAmbiguous(ParserTestCase):
321n/a """Test Optionals that partially match but are not subsets"""
322n/a
323n/a argument_signatures = [Sig('-foobar'), Sig('-foorab')]
324n/a failures = ['-f', '-f a', '-fa', '-foa', '-foo', '-fo', '-foo b']
325n/a successes = [
326n/a ('', NS(foobar=None, foorab=None)),
327n/a ('-foob a', NS(foobar='a', foorab=None)),
328n/a ('-foor a', NS(foobar=None, foorab='a')),
329n/a ('-fooba a', NS(foobar='a', foorab=None)),
330n/a ('-foora a', NS(foobar=None, foorab='a')),
331n/a ('-foobar a', NS(foobar='a', foorab=None)),
332n/a ('-foorab a', NS(foobar=None, foorab='a')),
333n/a ]
334n/a
335n/a
336n/aclass TestOptionalsNumeric(ParserTestCase):
337n/a """Test an Optional with a short opt string"""
338n/a
339n/a argument_signatures = [Sig('-1', dest='one')]
340n/a failures = ['-1', 'a', '-1 --foo', '-1 -y', '-1 -1', '-1 -2']
341n/a successes = [
342n/a ('', NS(one=None)),
343n/a ('-1 a', NS(one='a')),
344n/a ('-1a', NS(one='a')),
345n/a ('-1-2', NS(one='-2')),
346n/a ]
347n/a
348n/a
349n/aclass TestOptionalsDoubleDash(ParserTestCase):
350n/a """Test an Optional with a double-dash option string"""
351n/a
352n/a argument_signatures = [Sig('--foo')]
353n/a failures = ['--foo', '-f', '-f a', 'a', '--foo -x', '--foo --bar']
354n/a successes = [
355n/a ('', NS(foo=None)),
356n/a ('--foo a', NS(foo='a')),
357n/a ('--foo=a', NS(foo='a')),
358n/a ('--foo -2.5', NS(foo='-2.5')),
359n/a ('--foo=-2.5', NS(foo='-2.5')),
360n/a ]
361n/a
362n/a
363n/aclass TestOptionalsDoubleDashPartialMatch(ParserTestCase):
364n/a """Tests partial matching with a double-dash option string"""
365n/a
366n/a argument_signatures = [
367n/a Sig('--badger', action='store_true'),
368n/a Sig('--bat'),
369n/a ]
370n/a failures = ['--bar', '--b', '--ba', '--b=2', '--ba=4', '--badge 5']
371n/a successes = [
372n/a ('', NS(badger=False, bat=None)),
373n/a ('--bat X', NS(badger=False, bat='X')),
374n/a ('--bad', NS(badger=True, bat=None)),
375n/a ('--badg', NS(badger=True, bat=None)),
376n/a ('--badge', NS(badger=True, bat=None)),
377n/a ('--badger', NS(badger=True, bat=None)),
378n/a ]
379n/a
380n/a
381n/aclass TestOptionalsDoubleDashPrefixMatch(ParserTestCase):
382n/a """Tests when one double-dash option string is a prefix of another"""
383n/a
384n/a argument_signatures = [
385n/a Sig('--badger', action='store_true'),
386n/a Sig('--ba'),
387n/a ]
388n/a failures = ['--bar', '--b', '--ba', '--b=2', '--badge 5']
389n/a successes = [
390n/a ('', NS(badger=False, ba=None)),
391n/a ('--ba X', NS(badger=False, ba='X')),
392n/a ('--ba=X', NS(badger=False, ba='X')),
393n/a ('--bad', NS(badger=True, ba=None)),
394n/a ('--badg', NS(badger=True, ba=None)),
395n/a ('--badge', NS(badger=True, ba=None)),
396n/a ('--badger', NS(badger=True, ba=None)),
397n/a ]
398n/a
399n/a
400n/aclass TestOptionalsSingleDoubleDash(ParserTestCase):
401n/a """Test an Optional with single- and double-dash option strings"""
402n/a
403n/a argument_signatures = [
404n/a Sig('-f', action='store_true'),
405n/a Sig('--bar'),
406n/a Sig('-baz', action='store_const', const=42),
407n/a ]
408n/a failures = ['--bar', '-fbar', '-fbaz', '-bazf', '-b B', 'B']
409n/a successes = [
410n/a ('', NS(f=False, bar=None, baz=None)),
411n/a ('-f', NS(f=True, bar=None, baz=None)),
412n/a ('--ba B', NS(f=False, bar='B', baz=None)),
413n/a ('-f --bar B', NS(f=True, bar='B', baz=None)),
414n/a ('-f -b', NS(f=True, bar=None, baz=42)),
415n/a ('-ba -f', NS(f=True, bar=None, baz=42)),
416n/a ]
417n/a
418n/a
419n/aclass TestOptionalsAlternatePrefixChars(ParserTestCase):
420n/a """Test an Optional with option strings with custom prefixes"""
421n/a
422n/a parser_signature = Sig(prefix_chars='+:/', add_help=False)
423n/a argument_signatures = [
424n/a Sig('+f', action='store_true'),
425n/a Sig('::bar'),
426n/a Sig('/baz', action='store_const', const=42),
427n/a ]
428n/a failures = ['--bar', '-fbar', '-b B', 'B', '-f', '--bar B', '-baz', '-h', '--help', '+h', '::help', '/help']
429n/a successes = [
430n/a ('', NS(f=False, bar=None, baz=None)),
431n/a ('+f', NS(f=True, bar=None, baz=None)),
432n/a ('::ba B', NS(f=False, bar='B', baz=None)),
433n/a ('+f ::bar B', NS(f=True, bar='B', baz=None)),
434n/a ('+f /b', NS(f=True, bar=None, baz=42)),
435n/a ('/ba +f', NS(f=True, bar=None, baz=42)),
436n/a ]
437n/a
438n/a
439n/aclass TestOptionalsAlternatePrefixCharsAddedHelp(ParserTestCase):
440n/a """When ``-`` not in prefix_chars, default operators created for help
441n/a should use the prefix_chars in use rather than - or --
442n/a http://bugs.python.org/issue9444"""
443n/a
444n/a parser_signature = Sig(prefix_chars='+:/', add_help=True)
445n/a argument_signatures = [
446n/a Sig('+f', action='store_true'),
447n/a Sig('::bar'),
448n/a Sig('/baz', action='store_const', const=42),
449n/a ]
450n/a failures = ['--bar', '-fbar', '-b B', 'B', '-f', '--bar B', '-baz']
451n/a successes = [
452n/a ('', NS(f=False, bar=None, baz=None)),
453n/a ('+f', NS(f=True, bar=None, baz=None)),
454n/a ('::ba B', NS(f=False, bar='B', baz=None)),
455n/a ('+f ::bar B', NS(f=True, bar='B', baz=None)),
456n/a ('+f /b', NS(f=True, bar=None, baz=42)),
457n/a ('/ba +f', NS(f=True, bar=None, baz=42))
458n/a ]
459n/a
460n/a
461n/aclass TestOptionalsAlternatePrefixCharsMultipleShortArgs(ParserTestCase):
462n/a """Verify that Optionals must be called with their defined prefixes"""
463n/a
464n/a parser_signature = Sig(prefix_chars='+-', add_help=False)
465n/a argument_signatures = [
466n/a Sig('-x', action='store_true'),
467n/a Sig('+y', action='store_true'),
468n/a Sig('+z', action='store_true'),
469n/a ]
470n/a failures = ['-w',
471n/a '-xyz',
472n/a '+x',
473n/a '-y',
474n/a '+xyz',
475n/a ]
476n/a successes = [
477n/a ('', NS(x=False, y=False, z=False)),
478n/a ('-x', NS(x=True, y=False, z=False)),
479n/a ('+y -x', NS(x=True, y=True, z=False)),
480n/a ('+yz -x', NS(x=True, y=True, z=True)),
481n/a ]
482n/a
483n/a
484n/aclass TestOptionalsShortLong(ParserTestCase):
485n/a """Test a combination of single- and double-dash option strings"""
486n/a
487n/a argument_signatures = [
488n/a Sig('-v', '--verbose', '-n', '--noisy', action='store_true'),
489n/a ]
490n/a failures = ['--x --verbose', '-N', 'a', '-v x']
491n/a successes = [
492n/a ('', NS(verbose=False)),
493n/a ('-v', NS(verbose=True)),
494n/a ('--verbose', NS(verbose=True)),
495n/a ('-n', NS(verbose=True)),
496n/a ('--noisy', NS(verbose=True)),
497n/a ]
498n/a
499n/a
500n/aclass TestOptionalsDest(ParserTestCase):
501n/a """Tests various means of setting destination"""
502n/a
503n/a argument_signatures = [Sig('--foo-bar'), Sig('--baz', dest='zabbaz')]
504n/a failures = ['a']
505n/a successes = [
506n/a ('--foo-bar f', NS(foo_bar='f', zabbaz=None)),
507n/a ('--baz g', NS(foo_bar=None, zabbaz='g')),
508n/a ('--foo-bar h --baz i', NS(foo_bar='h', zabbaz='i')),
509n/a ('--baz j --foo-bar k', NS(foo_bar='k', zabbaz='j')),
510n/a ]
511n/a
512n/a
513n/aclass TestOptionalsDefault(ParserTestCase):
514n/a """Tests specifying a default for an Optional"""
515n/a
516n/a argument_signatures = [Sig('-x'), Sig('-y', default=42)]
517n/a failures = ['a']
518n/a successes = [
519n/a ('', NS(x=None, y=42)),
520n/a ('-xx', NS(x='x', y=42)),
521n/a ('-yy', NS(x=None, y='y')),
522n/a ]
523n/a
524n/a
525n/aclass TestOptionalsNargsDefault(ParserTestCase):
526n/a """Tests not specifying the number of args for an Optional"""
527n/a
528n/a argument_signatures = [Sig('-x')]
529n/a failures = ['a', '-x']
530n/a successes = [
531n/a ('', NS(x=None)),
532n/a ('-x a', NS(x='a')),
533n/a ]
534n/a
535n/a
536n/aclass TestOptionalsNargs1(ParserTestCase):
537n/a """Tests specifying 1 arg for an Optional"""
538n/a
539n/a argument_signatures = [Sig('-x', nargs=1)]
540n/a failures = ['a', '-x']
541n/a successes = [
542n/a ('', NS(x=None)),
543n/a ('-x a', NS(x=['a'])),
544n/a ]
545n/a
546n/a
547n/aclass TestOptionalsNargs3(ParserTestCase):
548n/a """Tests specifying 3 args for an Optional"""
549n/a
550n/a argument_signatures = [Sig('-x', nargs=3)]
551n/a failures = ['a', '-x', '-x a', '-x a b', 'a -x', 'a -x b']
552n/a successes = [
553n/a ('', NS(x=None)),
554n/a ('-x a b c', NS(x=['a', 'b', 'c'])),
555n/a ]
556n/a
557n/a
558n/aclass TestOptionalsNargsOptional(ParserTestCase):
559n/a """Tests specifying an Optional arg for an Optional"""
560n/a
561n/a argument_signatures = [
562n/a Sig('-w', nargs='?'),
563n/a Sig('-x', nargs='?', const=42),
564n/a Sig('-y', nargs='?', default='spam'),
565n/a Sig('-z', nargs='?', type=int, const='42', default='84'),
566n/a ]
567n/a failures = ['2']
568n/a successes = [
569n/a ('', NS(w=None, x=None, y='spam', z=84)),
570n/a ('-w', NS(w=None, x=None, y='spam', z=84)),
571n/a ('-w 2', NS(w='2', x=None, y='spam', z=84)),
572n/a ('-x', NS(w=None, x=42, y='spam', z=84)),
573n/a ('-x 2', NS(w=None, x='2', y='spam', z=84)),
574n/a ('-y', NS(w=None, x=None, y=None, z=84)),
575n/a ('-y 2', NS(w=None, x=None, y='2', z=84)),
576n/a ('-z', NS(w=None, x=None, y='spam', z=42)),
577n/a ('-z 2', NS(w=None, x=None, y='spam', z=2)),
578n/a ]
579n/a
580n/a
581n/aclass TestOptionalsNargsZeroOrMore(ParserTestCase):
582n/a """Tests specifying args for an Optional that accepts zero or more"""
583n/a
584n/a argument_signatures = [
585n/a Sig('-x', nargs='*'),
586n/a Sig('-y', nargs='*', default='spam'),
587n/a ]
588n/a failures = ['a']
589n/a successes = [
590n/a ('', NS(x=None, y='spam')),
591n/a ('-x', NS(x=[], y='spam')),
592n/a ('-x a', NS(x=['a'], y='spam')),
593n/a ('-x a b', NS(x=['a', 'b'], y='spam')),
594n/a ('-y', NS(x=None, y=[])),
595n/a ('-y a', NS(x=None, y=['a'])),
596n/a ('-y a b', NS(x=None, y=['a', 'b'])),
597n/a ]
598n/a
599n/a
600n/aclass TestOptionalsNargsOneOrMore(ParserTestCase):
601n/a """Tests specifying args for an Optional that accepts one or more"""
602n/a
603n/a argument_signatures = [
604n/a Sig('-x', nargs='+'),
605n/a Sig('-y', nargs='+', default='spam'),
606n/a ]
607n/a failures = ['a', '-x', '-y', 'a -x', 'a -y b']
608n/a successes = [
609n/a ('', NS(x=None, y='spam')),
610n/a ('-x a', NS(x=['a'], y='spam')),
611n/a ('-x a b', NS(x=['a', 'b'], y='spam')),
612n/a ('-y a', NS(x=None, y=['a'])),
613n/a ('-y a b', NS(x=None, y=['a', 'b'])),
614n/a ]
615n/a
616n/a
617n/aclass TestOptionalsChoices(ParserTestCase):
618n/a """Tests specifying the choices for an Optional"""
619n/a
620n/a argument_signatures = [
621n/a Sig('-f', choices='abc'),
622n/a Sig('-g', type=int, choices=range(5))]
623n/a failures = ['a', '-f d', '-fad', '-ga', '-g 6']
624n/a successes = [
625n/a ('', NS(f=None, g=None)),
626n/a ('-f a', NS(f='a', g=None)),
627n/a ('-f c', NS(f='c', g=None)),
628n/a ('-g 0', NS(f=None, g=0)),
629n/a ('-g 03', NS(f=None, g=3)),
630n/a ('-fb -g4', NS(f='b', g=4)),
631n/a ]
632n/a
633n/a
634n/aclass TestOptionalsRequired(ParserTestCase):
635n/a """Tests an optional action that is required"""
636n/a
637n/a argument_signatures = [
638n/a Sig('-x', type=int, required=True),
639n/a ]
640n/a failures = ['a', '']
641n/a successes = [
642n/a ('-x 1', NS(x=1)),
643n/a ('-x42', NS(x=42)),
644n/a ]
645n/a
646n/a
647n/aclass TestOptionalsActionStore(ParserTestCase):
648n/a """Tests the store action for an Optional"""
649n/a
650n/a argument_signatures = [Sig('-x', action='store')]
651n/a failures = ['a', 'a -x']
652n/a successes = [
653n/a ('', NS(x=None)),
654n/a ('-xfoo', NS(x='foo')),
655n/a ]
656n/a
657n/a
658n/aclass TestOptionalsActionStoreConst(ParserTestCase):
659n/a """Tests the store_const action for an Optional"""
660n/a
661n/a argument_signatures = [Sig('-y', action='store_const', const=object)]
662n/a failures = ['a']
663n/a successes = [
664n/a ('', NS(y=None)),
665n/a ('-y', NS(y=object)),
666n/a ]
667n/a
668n/a
669n/aclass TestOptionalsActionStoreFalse(ParserTestCase):
670n/a """Tests the store_false action for an Optional"""
671n/a
672n/a argument_signatures = [Sig('-z', action='store_false')]
673n/a failures = ['a', '-za', '-z a']
674n/a successes = [
675n/a ('', NS(z=True)),
676n/a ('-z', NS(z=False)),
677n/a ]
678n/a
679n/a
680n/aclass TestOptionalsActionStoreTrue(ParserTestCase):
681n/a """Tests the store_true action for an Optional"""
682n/a
683n/a argument_signatures = [Sig('--apple', action='store_true')]
684n/a failures = ['a', '--apple=b', '--apple b']
685n/a successes = [
686n/a ('', NS(apple=False)),
687n/a ('--apple', NS(apple=True)),
688n/a ]
689n/a
690n/a
691n/aclass TestOptionalsActionAppend(ParserTestCase):
692n/a """Tests the append action for an Optional"""
693n/a
694n/a argument_signatures = [Sig('--baz', action='append')]
695n/a failures = ['a', '--baz', 'a --baz', '--baz a b']
696n/a successes = [
697n/a ('', NS(baz=None)),
698n/a ('--baz a', NS(baz=['a'])),
699n/a ('--baz a --baz b', NS(baz=['a', 'b'])),
700n/a ]
701n/a
702n/a
703n/aclass TestOptionalsActionAppendWithDefault(ParserTestCase):
704n/a """Tests the append action for an Optional"""
705n/a
706n/a argument_signatures = [Sig('--baz', action='append', default=['X'])]
707n/a failures = ['a', '--baz', 'a --baz', '--baz a b']
708n/a successes = [
709n/a ('', NS(baz=['X'])),
710n/a ('--baz a', NS(baz=['X', 'a'])),
711n/a ('--baz a --baz b', NS(baz=['X', 'a', 'b'])),
712n/a ]
713n/a
714n/a
715n/aclass TestOptionalsActionAppendConst(ParserTestCase):
716n/a """Tests the append_const action for an Optional"""
717n/a
718n/a argument_signatures = [
719n/a Sig('-b', action='append_const', const=Exception),
720n/a Sig('-c', action='append', dest='b'),
721n/a ]
722n/a failures = ['a', '-c', 'a -c', '-bx', '-b x']
723n/a successes = [
724n/a ('', NS(b=None)),
725n/a ('-b', NS(b=[Exception])),
726n/a ('-b -cx -b -cyz', NS(b=[Exception, 'x', Exception, 'yz'])),
727n/a ]
728n/a
729n/a
730n/aclass TestOptionalsActionAppendConstWithDefault(ParserTestCase):
731n/a """Tests the append_const action for an Optional"""
732n/a
733n/a argument_signatures = [
734n/a Sig('-b', action='append_const', const=Exception, default=['X']),
735n/a Sig('-c', action='append', dest='b'),
736n/a ]
737n/a failures = ['a', '-c', 'a -c', '-bx', '-b x']
738n/a successes = [
739n/a ('', NS(b=['X'])),
740n/a ('-b', NS(b=['X', Exception])),
741n/a ('-b -cx -b -cyz', NS(b=['X', Exception, 'x', Exception, 'yz'])),
742n/a ]
743n/a
744n/a
745n/aclass TestOptionalsActionCount(ParserTestCase):
746n/a """Tests the count action for an Optional"""
747n/a
748n/a argument_signatures = [Sig('-x', action='count')]
749n/a failures = ['a', '-x a', '-x b', '-x a -x b']
750n/a successes = [
751n/a ('', NS(x=None)),
752n/a ('-x', NS(x=1)),
753n/a ]
754n/a
755n/a
756n/aclass TestOptionalsAllowLongAbbreviation(ParserTestCase):
757n/a """Allow long options to be abbreviated unambiguously"""
758n/a
759n/a argument_signatures = [
760n/a Sig('--foo'),
761n/a Sig('--foobaz'),
762n/a Sig('--fooble', action='store_true'),
763n/a ]
764n/a failures = ['--foob 5', '--foob']
765n/a successes = [
766n/a ('', NS(foo=None, foobaz=None, fooble=False)),
767n/a ('--foo 7', NS(foo='7', foobaz=None, fooble=False)),
768n/a ('--fooba a', NS(foo=None, foobaz='a', fooble=False)),
769n/a ('--foobl --foo g', NS(foo='g', foobaz=None, fooble=True)),
770n/a ]
771n/a
772n/a
773n/aclass TestOptionalsDisallowLongAbbreviation(ParserTestCase):
774n/a """Do not allow abbreviations of long options at all"""
775n/a
776n/a parser_signature = Sig(allow_abbrev=False)
777n/a argument_signatures = [
778n/a Sig('--foo'),
779n/a Sig('--foodle', action='store_true'),
780n/a Sig('--foonly'),
781n/a ]
782n/a failures = ['-foon 3', '--foon 3', '--food', '--food --foo 2']
783n/a successes = [
784n/a ('', NS(foo=None, foodle=False, foonly=None)),
785n/a ('--foo 3', NS(foo='3', foodle=False, foonly=None)),
786n/a ('--foonly 7 --foodle --foo 2', NS(foo='2', foodle=True, foonly='7')),
787n/a ]
788n/a
789n/a# ================
790n/a# Positional tests
791n/a# ================
792n/a
793n/aclass TestPositionalsNargsNone(ParserTestCase):
794n/a """Test a Positional that doesn't specify nargs"""
795n/a
796n/a argument_signatures = [Sig('foo')]
797n/a failures = ['', '-x', 'a b']
798n/a successes = [
799n/a ('a', NS(foo='a')),
800n/a ]
801n/a
802n/a
803n/aclass TestPositionalsNargs1(ParserTestCase):
804n/a """Test a Positional that specifies an nargs of 1"""
805n/a
806n/a argument_signatures = [Sig('foo', nargs=1)]
807n/a failures = ['', '-x', 'a b']
808n/a successes = [
809n/a ('a', NS(foo=['a'])),
810n/a ]
811n/a
812n/a
813n/aclass TestPositionalsNargs2(ParserTestCase):
814n/a """Test a Positional that specifies an nargs of 2"""
815n/a
816n/a argument_signatures = [Sig('foo', nargs=2)]
817n/a failures = ['', 'a', '-x', 'a b c']
818n/a successes = [
819n/a ('a b', NS(foo=['a', 'b'])),
820n/a ]
821n/a
822n/a
823n/aclass TestPositionalsNargsZeroOrMore(ParserTestCase):
824n/a """Test a Positional that specifies unlimited nargs"""
825n/a
826n/a argument_signatures = [Sig('foo', nargs='*')]
827n/a failures = ['-x']
828n/a successes = [
829n/a ('', NS(foo=[])),
830n/a ('a', NS(foo=['a'])),
831n/a ('a b', NS(foo=['a', 'b'])),
832n/a ]
833n/a
834n/a
835n/aclass TestPositionalsNargsZeroOrMoreDefault(ParserTestCase):
836n/a """Test a Positional that specifies unlimited nargs and a default"""
837n/a
838n/a argument_signatures = [Sig('foo', nargs='*', default='bar')]
839n/a failures = ['-x']
840n/a successes = [
841n/a ('', NS(foo='bar')),
842n/a ('a', NS(foo=['a'])),
843n/a ('a b', NS(foo=['a', 'b'])),
844n/a ]
845n/a
846n/a
847n/aclass TestPositionalsNargsOneOrMore(ParserTestCase):
848n/a """Test a Positional that specifies one or more nargs"""
849n/a
850n/a argument_signatures = [Sig('foo', nargs='+')]
851n/a failures = ['', '-x']
852n/a successes = [
853n/a ('a', NS(foo=['a'])),
854n/a ('a b', NS(foo=['a', 'b'])),
855n/a ]
856n/a
857n/a
858n/aclass TestPositionalsNargsOptional(ParserTestCase):
859n/a """Tests an Optional Positional"""
860n/a
861n/a argument_signatures = [Sig('foo', nargs='?')]
862n/a failures = ['-x', 'a b']
863n/a successes = [
864n/a ('', NS(foo=None)),
865n/a ('a', NS(foo='a')),
866n/a ]
867n/a
868n/a
869n/aclass TestPositionalsNargsOptionalDefault(ParserTestCase):
870n/a """Tests an Optional Positional with a default value"""
871n/a
872n/a argument_signatures = [Sig('foo', nargs='?', default=42)]
873n/a failures = ['-x', 'a b']
874n/a successes = [
875n/a ('', NS(foo=42)),
876n/a ('a', NS(foo='a')),
877n/a ]
878n/a
879n/a
880n/aclass TestPositionalsNargsOptionalConvertedDefault(ParserTestCase):
881n/a """Tests an Optional Positional with a default value
882n/a that needs to be converted to the appropriate type.
883n/a """
884n/a
885n/a argument_signatures = [
886n/a Sig('foo', nargs='?', type=int, default='42'),
887n/a ]
888n/a failures = ['-x', 'a b', '1 2']
889n/a successes = [
890n/a ('', NS(foo=42)),
891n/a ('1', NS(foo=1)),
892n/a ]
893n/a
894n/a
895n/aclass TestPositionalsNargsNoneNone(ParserTestCase):
896n/a """Test two Positionals that don't specify nargs"""
897n/a
898n/a argument_signatures = [Sig('foo'), Sig('bar')]
899n/a failures = ['', '-x', 'a', 'a b c']
900n/a successes = [
901n/a ('a b', NS(foo='a', bar='b')),
902n/a ]
903n/a
904n/a
905n/aclass TestPositionalsNargsNone1(ParserTestCase):
906n/a """Test a Positional with no nargs followed by one with 1"""
907n/a
908n/a argument_signatures = [Sig('foo'), Sig('bar', nargs=1)]
909n/a failures = ['', '--foo', 'a', 'a b c']
910n/a successes = [
911n/a ('a b', NS(foo='a', bar=['b'])),
912n/a ]
913n/a
914n/a
915n/aclass TestPositionalsNargs2None(ParserTestCase):
916n/a """Test a Positional with 2 nargs followed by one with none"""
917n/a
918n/a argument_signatures = [Sig('foo', nargs=2), Sig('bar')]
919n/a failures = ['', '--foo', 'a', 'a b', 'a b c d']
920n/a successes = [
921n/a ('a b c', NS(foo=['a', 'b'], bar='c')),
922n/a ]
923n/a
924n/a
925n/aclass TestPositionalsNargsNoneZeroOrMore(ParserTestCase):
926n/a """Test a Positional with no nargs followed by one with unlimited"""
927n/a
928n/a argument_signatures = [Sig('foo'), Sig('bar', nargs='*')]
929n/a failures = ['', '--foo']
930n/a successes = [
931n/a ('a', NS(foo='a', bar=[])),
932n/a ('a b', NS(foo='a', bar=['b'])),
933n/a ('a b c', NS(foo='a', bar=['b', 'c'])),
934n/a ]
935n/a
936n/a
937n/aclass TestPositionalsNargsNoneOneOrMore(ParserTestCase):
938n/a """Test a Positional with no nargs followed by one with one or more"""
939n/a
940n/a argument_signatures = [Sig('foo'), Sig('bar', nargs='+')]
941n/a failures = ['', '--foo', 'a']
942n/a successes = [
943n/a ('a b', NS(foo='a', bar=['b'])),
944n/a ('a b c', NS(foo='a', bar=['b', 'c'])),
945n/a ]
946n/a
947n/a
948n/aclass TestPositionalsNargsNoneOptional(ParserTestCase):
949n/a """Test a Positional with no nargs followed by one with an Optional"""
950n/a
951n/a argument_signatures = [Sig('foo'), Sig('bar', nargs='?')]
952n/a failures = ['', '--foo', 'a b c']
953n/a successes = [
954n/a ('a', NS(foo='a', bar=None)),
955n/a ('a b', NS(foo='a', bar='b')),
956n/a ]
957n/a
958n/a
959n/aclass TestPositionalsNargsZeroOrMoreNone(ParserTestCase):
960n/a """Test a Positional with unlimited nargs followed by one with none"""
961n/a
962n/a argument_signatures = [Sig('foo', nargs='*'), Sig('bar')]
963n/a failures = ['', '--foo']
964n/a successes = [
965n/a ('a', NS(foo=[], bar='a')),
966n/a ('a b', NS(foo=['a'], bar='b')),
967n/a ('a b c', NS(foo=['a', 'b'], bar='c')),
968n/a ]
969n/a
970n/a
971n/aclass TestPositionalsNargsOneOrMoreNone(ParserTestCase):
972n/a """Test a Positional with one or more nargs followed by one with none"""
973n/a
974n/a argument_signatures = [Sig('foo', nargs='+'), Sig('bar')]
975n/a failures = ['', '--foo', 'a']
976n/a successes = [
977n/a ('a b', NS(foo=['a'], bar='b')),
978n/a ('a b c', NS(foo=['a', 'b'], bar='c')),
979n/a ]
980n/a
981n/a
982n/aclass TestPositionalsNargsOptionalNone(ParserTestCase):
983n/a """Test a Positional with an Optional nargs followed by one with none"""
984n/a
985n/a argument_signatures = [Sig('foo', nargs='?', default=42), Sig('bar')]
986n/a failures = ['', '--foo', 'a b c']
987n/a successes = [
988n/a ('a', NS(foo=42, bar='a')),
989n/a ('a b', NS(foo='a', bar='b')),
990n/a ]
991n/a
992n/a
993n/aclass TestPositionalsNargs2ZeroOrMore(ParserTestCase):
994n/a """Test a Positional with 2 nargs followed by one with unlimited"""
995n/a
996n/a argument_signatures = [Sig('foo', nargs=2), Sig('bar', nargs='*')]
997n/a failures = ['', '--foo', 'a']
998n/a successes = [
999n/a ('a b', NS(foo=['a', 'b'], bar=[])),
1000n/a ('a b c', NS(foo=['a', 'b'], bar=['c'])),
1001n/a ]
1002n/a
1003n/a
1004n/aclass TestPositionalsNargs2OneOrMore(ParserTestCase):
1005n/a """Test a Positional with 2 nargs followed by one with one or more"""
1006n/a
1007n/a argument_signatures = [Sig('foo', nargs=2), Sig('bar', nargs='+')]
1008n/a failures = ['', '--foo', 'a', 'a b']
1009n/a successes = [
1010n/a ('a b c', NS(foo=['a', 'b'], bar=['c'])),
1011n/a ]
1012n/a
1013n/a
1014n/aclass TestPositionalsNargs2Optional(ParserTestCase):
1015n/a """Test a Positional with 2 nargs followed by one optional"""
1016n/a
1017n/a argument_signatures = [Sig('foo', nargs=2), Sig('bar', nargs='?')]
1018n/a failures = ['', '--foo', 'a', 'a b c d']
1019n/a successes = [
1020n/a ('a b', NS(foo=['a', 'b'], bar=None)),
1021n/a ('a b c', NS(foo=['a', 'b'], bar='c')),
1022n/a ]
1023n/a
1024n/a
1025n/aclass TestPositionalsNargsZeroOrMore1(ParserTestCase):
1026n/a """Test a Positional with unlimited nargs followed by one with 1"""
1027n/a
1028n/a argument_signatures = [Sig('foo', nargs='*'), Sig('bar', nargs=1)]
1029n/a failures = ['', '--foo', ]
1030n/a successes = [
1031n/a ('a', NS(foo=[], bar=['a'])),
1032n/a ('a b', NS(foo=['a'], bar=['b'])),
1033n/a ('a b c', NS(foo=['a', 'b'], bar=['c'])),
1034n/a ]
1035n/a
1036n/a
1037n/aclass TestPositionalsNargsOneOrMore1(ParserTestCase):
1038n/a """Test a Positional with one or more nargs followed by one with 1"""
1039n/a
1040n/a argument_signatures = [Sig('foo', nargs='+'), Sig('bar', nargs=1)]
1041n/a failures = ['', '--foo', 'a']
1042n/a successes = [
1043n/a ('a b', NS(foo=['a'], bar=['b'])),
1044n/a ('a b c', NS(foo=['a', 'b'], bar=['c'])),
1045n/a ]
1046n/a
1047n/a
1048n/aclass TestPositionalsNargsOptional1(ParserTestCase):
1049n/a """Test a Positional with an Optional nargs followed by one with 1"""
1050n/a
1051n/a argument_signatures = [Sig('foo', nargs='?'), Sig('bar', nargs=1)]
1052n/a failures = ['', '--foo', 'a b c']
1053n/a successes = [
1054n/a ('a', NS(foo=None, bar=['a'])),
1055n/a ('a b', NS(foo='a', bar=['b'])),
1056n/a ]
1057n/a
1058n/a
1059n/aclass TestPositionalsNargsNoneZeroOrMore1(ParserTestCase):
1060n/a """Test three Positionals: no nargs, unlimited nargs and 1 nargs"""
1061n/a
1062n/a argument_signatures = [
1063n/a Sig('foo'),
1064n/a Sig('bar', nargs='*'),
1065n/a Sig('baz', nargs=1),
1066n/a ]
1067n/a failures = ['', '--foo', 'a']
1068n/a successes = [
1069n/a ('a b', NS(foo='a', bar=[], baz=['b'])),
1070n/a ('a b c', NS(foo='a', bar=['b'], baz=['c'])),
1071n/a ]
1072n/a
1073n/a
1074n/aclass TestPositionalsNargsNoneOneOrMore1(ParserTestCase):
1075n/a """Test three Positionals: no nargs, one or more nargs and 1 nargs"""
1076n/a
1077n/a argument_signatures = [
1078n/a Sig('foo'),
1079n/a Sig('bar', nargs='+'),
1080n/a Sig('baz', nargs=1),
1081n/a ]
1082n/a failures = ['', '--foo', 'a', 'b']
1083n/a successes = [
1084n/a ('a b c', NS(foo='a', bar=['b'], baz=['c'])),
1085n/a ('a b c d', NS(foo='a', bar=['b', 'c'], baz=['d'])),
1086n/a ]
1087n/a
1088n/a
1089n/aclass TestPositionalsNargsNoneOptional1(ParserTestCase):
1090n/a """Test three Positionals: no nargs, optional narg and 1 nargs"""
1091n/a
1092n/a argument_signatures = [
1093n/a Sig('foo'),
1094n/a Sig('bar', nargs='?', default=0.625),
1095n/a Sig('baz', nargs=1),
1096n/a ]
1097n/a failures = ['', '--foo', 'a']
1098n/a successes = [
1099n/a ('a b', NS(foo='a', bar=0.625, baz=['b'])),
1100n/a ('a b c', NS(foo='a', bar='b', baz=['c'])),
1101n/a ]
1102n/a
1103n/a
1104n/aclass TestPositionalsNargsOptionalOptional(ParserTestCase):
1105n/a """Test two optional nargs"""
1106n/a
1107n/a argument_signatures = [
1108n/a Sig('foo', nargs='?'),
1109n/a Sig('bar', nargs='?', default=42),
1110n/a ]
1111n/a failures = ['--foo', 'a b c']
1112n/a successes = [
1113n/a ('', NS(foo=None, bar=42)),
1114n/a ('a', NS(foo='a', bar=42)),
1115n/a ('a b', NS(foo='a', bar='b')),
1116n/a ]
1117n/a
1118n/a
1119n/aclass TestPositionalsNargsOptionalZeroOrMore(ParserTestCase):
1120n/a """Test an Optional narg followed by unlimited nargs"""
1121n/a
1122n/a argument_signatures = [Sig('foo', nargs='?'), Sig('bar', nargs='*')]
1123n/a failures = ['--foo']
1124n/a successes = [
1125n/a ('', NS(foo=None, bar=[])),
1126n/a ('a', NS(foo='a', bar=[])),
1127n/a ('a b', NS(foo='a', bar=['b'])),
1128n/a ('a b c', NS(foo='a', bar=['b', 'c'])),
1129n/a ]
1130n/a
1131n/a
1132n/aclass TestPositionalsNargsOptionalOneOrMore(ParserTestCase):
1133n/a """Test an Optional narg followed by one or more nargs"""
1134n/a
1135n/a argument_signatures = [Sig('foo', nargs='?'), Sig('bar', nargs='+')]
1136n/a failures = ['', '--foo']
1137n/a successes = [
1138n/a ('a', NS(foo=None, bar=['a'])),
1139n/a ('a b', NS(foo='a', bar=['b'])),
1140n/a ('a b c', NS(foo='a', bar=['b', 'c'])),
1141n/a ]
1142n/a
1143n/a
1144n/aclass TestPositionalsChoicesString(ParserTestCase):
1145n/a """Test a set of single-character choices"""
1146n/a
1147n/a argument_signatures = [Sig('spam', choices=set('abcdefg'))]
1148n/a failures = ['', '--foo', 'h', '42', 'ef']
1149n/a successes = [
1150n/a ('a', NS(spam='a')),
1151n/a ('g', NS(spam='g')),
1152n/a ]
1153n/a
1154n/a
1155n/aclass TestPositionalsChoicesInt(ParserTestCase):
1156n/a """Test a set of integer choices"""
1157n/a
1158n/a argument_signatures = [Sig('spam', type=int, choices=range(20))]
1159n/a failures = ['', '--foo', 'h', '42', 'ef']
1160n/a successes = [
1161n/a ('4', NS(spam=4)),
1162n/a ('15', NS(spam=15)),
1163n/a ]
1164n/a
1165n/a
1166n/aclass TestPositionalsActionAppend(ParserTestCase):
1167n/a """Test the 'append' action"""
1168n/a
1169n/a argument_signatures = [
1170n/a Sig('spam', action='append'),
1171n/a Sig('spam', action='append', nargs=2),
1172n/a ]
1173n/a failures = ['', '--foo', 'a', 'a b', 'a b c d']
1174n/a successes = [
1175n/a ('a b c', NS(spam=['a', ['b', 'c']])),
1176n/a ]
1177n/a
1178n/a# ========================================
1179n/a# Combined optionals and positionals tests
1180n/a# ========================================
1181n/a
1182n/aclass TestOptionalsNumericAndPositionals(ParserTestCase):
1183n/a """Tests negative number args when numeric options are present"""
1184n/a
1185n/a argument_signatures = [
1186n/a Sig('x', nargs='?'),
1187n/a Sig('-4', dest='y', action='store_true'),
1188n/a ]
1189n/a failures = ['-2', '-315']
1190n/a successes = [
1191n/a ('', NS(x=None, y=False)),
1192n/a ('a', NS(x='a', y=False)),
1193n/a ('-4', NS(x=None, y=True)),
1194n/a ('-4 a', NS(x='a', y=True)),
1195n/a ]
1196n/a
1197n/a
1198n/aclass TestOptionalsAlmostNumericAndPositionals(ParserTestCase):
1199n/a """Tests negative number args when almost numeric options are present"""
1200n/a
1201n/a argument_signatures = [
1202n/a Sig('x', nargs='?'),
1203n/a Sig('-k4', dest='y', action='store_true'),
1204n/a ]
1205n/a failures = ['-k3']
1206n/a successes = [
1207n/a ('', NS(x=None, y=False)),
1208n/a ('-2', NS(x='-2', y=False)),
1209n/a ('a', NS(x='a', y=False)),
1210n/a ('-k4', NS(x=None, y=True)),
1211n/a ('-k4 a', NS(x='a', y=True)),
1212n/a ]
1213n/a
1214n/a
1215n/aclass TestEmptyAndSpaceContainingArguments(ParserTestCase):
1216n/a
1217n/a argument_signatures = [
1218n/a Sig('x', nargs='?'),
1219n/a Sig('-y', '--yyy', dest='y'),
1220n/a ]
1221n/a failures = ['-y']
1222n/a successes = [
1223n/a ([''], NS(x='', y=None)),
1224n/a (['a badger'], NS(x='a badger', y=None)),
1225n/a (['-a badger'], NS(x='-a badger', y=None)),
1226n/a (['-y', ''], NS(x=None, y='')),
1227n/a (['-y', 'a badger'], NS(x=None, y='a badger')),
1228n/a (['-y', '-a badger'], NS(x=None, y='-a badger')),
1229n/a (['--yyy=a badger'], NS(x=None, y='a badger')),
1230n/a (['--yyy=-a badger'], NS(x=None, y='-a badger')),
1231n/a ]
1232n/a
1233n/a
1234n/aclass TestPrefixCharacterOnlyArguments(ParserTestCase):
1235n/a
1236n/a parser_signature = Sig(prefix_chars='-+')
1237n/a argument_signatures = [
1238n/a Sig('-', dest='x', nargs='?', const='badger'),
1239n/a Sig('+', dest='y', type=int, default=42),
1240n/a Sig('-+-', dest='z', action='store_true'),
1241n/a ]
1242n/a failures = ['-y', '+ -']
1243n/a successes = [
1244n/a ('', NS(x=None, y=42, z=False)),
1245n/a ('-', NS(x='badger', y=42, z=False)),
1246n/a ('- X', NS(x='X', y=42, z=False)),
1247n/a ('+ -3', NS(x=None, y=-3, z=False)),
1248n/a ('-+-', NS(x=None, y=42, z=True)),
1249n/a ('- ===', NS(x='===', y=42, z=False)),
1250n/a ]
1251n/a
1252n/a
1253n/aclass TestNargsZeroOrMore(ParserTestCase):
1254n/a """Tests specifying args for an Optional that accepts zero or more"""
1255n/a
1256n/a argument_signatures = [Sig('-x', nargs='*'), Sig('y', nargs='*')]
1257n/a failures = []
1258n/a successes = [
1259n/a ('', NS(x=None, y=[])),
1260n/a ('-x', NS(x=[], y=[])),
1261n/a ('-x a', NS(x=['a'], y=[])),
1262n/a ('-x a -- b', NS(x=['a'], y=['b'])),
1263n/a ('a', NS(x=None, y=['a'])),
1264n/a ('a -x', NS(x=[], y=['a'])),
1265n/a ('a -x b', NS(x=['b'], y=['a'])),
1266n/a ]
1267n/a
1268n/a
1269n/aclass TestNargsRemainder(ParserTestCase):
1270n/a """Tests specifying a positional with nargs=REMAINDER"""
1271n/a
1272n/a argument_signatures = [Sig('x'), Sig('y', nargs='...'), Sig('-z')]
1273n/a failures = ['', '-z', '-z Z']
1274n/a successes = [
1275n/a ('X', NS(x='X', y=[], z=None)),
1276n/a ('-z Z X', NS(x='X', y=[], z='Z')),
1277n/a ('X A B -z Z', NS(x='X', y=['A', 'B', '-z', 'Z'], z=None)),
1278n/a ('X Y --foo', NS(x='X', y=['Y', '--foo'], z=None)),
1279n/a ]
1280n/a
1281n/a
1282n/aclass TestOptionLike(ParserTestCase):
1283n/a """Tests options that may or may not be arguments"""
1284n/a
1285n/a argument_signatures = [
1286n/a Sig('-x', type=float),
1287n/a Sig('-3', type=float, dest='y'),
1288n/a Sig('z', nargs='*'),
1289n/a ]
1290n/a failures = ['-x', '-y2.5', '-xa', '-x -a',
1291n/a '-x -3', '-x -3.5', '-3 -3.5',
1292n/a '-x -2.5', '-x -2.5 a', '-3 -.5',
1293n/a 'a x -1', '-x -1 a', '-3 -1 a']
1294n/a successes = [
1295n/a ('', NS(x=None, y=None, z=[])),
1296n/a ('-x 2.5', NS(x=2.5, y=None, z=[])),
1297n/a ('-x 2.5 a', NS(x=2.5, y=None, z=['a'])),
1298n/a ('-3.5', NS(x=None, y=0.5, z=[])),
1299n/a ('-3-.5', NS(x=None, y=-0.5, z=[])),
1300n/a ('-3 .5', NS(x=None, y=0.5, z=[])),
1301n/a ('a -3.5', NS(x=None, y=0.5, z=['a'])),
1302n/a ('a', NS(x=None, y=None, z=['a'])),
1303n/a ('a -x 1', NS(x=1.0, y=None, z=['a'])),
1304n/a ('-x 1 a', NS(x=1.0, y=None, z=['a'])),
1305n/a ('-3 1 a', NS(x=None, y=1.0, z=['a'])),
1306n/a ]
1307n/a
1308n/a
1309n/aclass TestDefaultSuppress(ParserTestCase):
1310n/a """Test actions with suppressed defaults"""
1311n/a
1312n/a argument_signatures = [
1313n/a Sig('foo', nargs='?', default=argparse.SUPPRESS),
1314n/a Sig('bar', nargs='*', default=argparse.SUPPRESS),
1315n/a Sig('--baz', action='store_true', default=argparse.SUPPRESS),
1316n/a ]
1317n/a failures = ['-x']
1318n/a successes = [
1319n/a ('', NS()),
1320n/a ('a', NS(foo='a')),
1321n/a ('a b', NS(foo='a', bar=['b'])),
1322n/a ('--baz', NS(baz=True)),
1323n/a ('a --baz', NS(foo='a', baz=True)),
1324n/a ('--baz a b', NS(foo='a', bar=['b'], baz=True)),
1325n/a ]
1326n/a
1327n/a
1328n/aclass TestParserDefaultSuppress(ParserTestCase):
1329n/a """Test actions with a parser-level default of SUPPRESS"""
1330n/a
1331n/a parser_signature = Sig(argument_default=argparse.SUPPRESS)
1332n/a argument_signatures = [
1333n/a Sig('foo', nargs='?'),
1334n/a Sig('bar', nargs='*'),
1335n/a Sig('--baz', action='store_true'),
1336n/a ]
1337n/a failures = ['-x']
1338n/a successes = [
1339n/a ('', NS()),
1340n/a ('a', NS(foo='a')),
1341n/a ('a b', NS(foo='a', bar=['b'])),
1342n/a ('--baz', NS(baz=True)),
1343n/a ('a --baz', NS(foo='a', baz=True)),
1344n/a ('--baz a b', NS(foo='a', bar=['b'], baz=True)),
1345n/a ]
1346n/a
1347n/a
1348n/aclass TestParserDefault42(ParserTestCase):
1349n/a """Test actions with a parser-level default of 42"""
1350n/a
1351n/a parser_signature = Sig(argument_default=42)
1352n/a argument_signatures = [
1353n/a Sig('--version', action='version', version='1.0'),
1354n/a Sig('foo', nargs='?'),
1355n/a Sig('bar', nargs='*'),
1356n/a Sig('--baz', action='store_true'),
1357n/a ]
1358n/a failures = ['-x']
1359n/a successes = [
1360n/a ('', NS(foo=42, bar=42, baz=42, version=42)),
1361n/a ('a', NS(foo='a', bar=42, baz=42, version=42)),
1362n/a ('a b', NS(foo='a', bar=['b'], baz=42, version=42)),
1363n/a ('--baz', NS(foo=42, bar=42, baz=True, version=42)),
1364n/a ('a --baz', NS(foo='a', bar=42, baz=True, version=42)),
1365n/a ('--baz a b', NS(foo='a', bar=['b'], baz=True, version=42)),
1366n/a ]
1367n/a
1368n/a
1369n/aclass TestArgumentsFromFile(TempDirMixin, ParserTestCase):
1370n/a """Test reading arguments from a file"""
1371n/a
1372n/a def setUp(self):
1373n/a super(TestArgumentsFromFile, self).setUp()
1374n/a file_texts = [
1375n/a ('hello', 'hello world!\n'),
1376n/a ('recursive', '-a\n'
1377n/a 'A\n'
1378n/a '@hello'),
1379n/a ('invalid', '@no-such-path\n'),
1380n/a ]
1381n/a for path, text in file_texts:
1382n/a file = open(path, 'w')
1383n/a file.write(text)
1384n/a file.close()
1385n/a
1386n/a parser_signature = Sig(fromfile_prefix_chars='@')
1387n/a argument_signatures = [
1388n/a Sig('-a'),
1389n/a Sig('x'),
1390n/a Sig('y', nargs='+'),
1391n/a ]
1392n/a failures = ['', '-b', 'X', '@invalid', '@missing']
1393n/a successes = [
1394n/a ('X Y', NS(a=None, x='X', y=['Y'])),
1395n/a ('X -a A Y Z', NS(a='A', x='X', y=['Y', 'Z'])),
1396n/a ('@hello X', NS(a=None, x='hello world!', y=['X'])),
1397n/a ('X @hello', NS(a=None, x='X', y=['hello world!'])),
1398n/a ('-a B @recursive Y Z', NS(a='A', x='hello world!', y=['Y', 'Z'])),
1399n/a ('X @recursive Z -a B', NS(a='B', x='X', y=['hello world!', 'Z'])),
1400n/a (["-a", "", "X", "Y"], NS(a='', x='X', y=['Y'])),
1401n/a ]
1402n/a
1403n/a
1404n/aclass TestArgumentsFromFileConverter(TempDirMixin, ParserTestCase):
1405n/a """Test reading arguments from a file"""
1406n/a
1407n/a def setUp(self):
1408n/a super(TestArgumentsFromFileConverter, self).setUp()
1409n/a file_texts = [
1410n/a ('hello', 'hello world!\n'),
1411n/a ]
1412n/a for path, text in file_texts:
1413n/a file = open(path, 'w')
1414n/a file.write(text)
1415n/a file.close()
1416n/a
1417n/a class FromFileConverterArgumentParser(ErrorRaisingArgumentParser):
1418n/a
1419n/a def convert_arg_line_to_args(self, arg_line):
1420n/a for arg in arg_line.split():
1421n/a if not arg.strip():
1422n/a continue
1423n/a yield arg
1424n/a parser_class = FromFileConverterArgumentParser
1425n/a parser_signature = Sig(fromfile_prefix_chars='@')
1426n/a argument_signatures = [
1427n/a Sig('y', nargs='+'),
1428n/a ]
1429n/a failures = []
1430n/a successes = [
1431n/a ('@hello X', NS(y=['hello', 'world!', 'X'])),
1432n/a ]
1433n/a
1434n/a
1435n/a# =====================
1436n/a# Type conversion tests
1437n/a# =====================
1438n/a
1439n/aclass TestFileTypeRepr(TestCase):
1440n/a
1441n/a def test_r(self):
1442n/a type = argparse.FileType('r')
1443n/a self.assertEqual("FileType('r')", repr(type))
1444n/a
1445n/a def test_wb_1(self):
1446n/a type = argparse.FileType('wb', 1)
1447n/a self.assertEqual("FileType('wb', 1)", repr(type))
1448n/a
1449n/a def test_r_latin(self):
1450n/a type = argparse.FileType('r', encoding='latin_1')
1451n/a self.assertEqual("FileType('r', encoding='latin_1')", repr(type))
1452n/a
1453n/a def test_w_big5_ignore(self):
1454n/a type = argparse.FileType('w', encoding='big5', errors='ignore')
1455n/a self.assertEqual("FileType('w', encoding='big5', errors='ignore')",
1456n/a repr(type))
1457n/a
1458n/a def test_r_1_replace(self):
1459n/a type = argparse.FileType('r', 1, errors='replace')
1460n/a self.assertEqual("FileType('r', 1, errors='replace')", repr(type))
1461n/a
1462n/a
1463n/aclass RFile(object):
1464n/a seen = {}
1465n/a
1466n/a def __init__(self, name):
1467n/a self.name = name
1468n/a
1469n/a def __eq__(self, other):
1470n/a if other in self.seen:
1471n/a text = self.seen[other]
1472n/a else:
1473n/a text = self.seen[other] = other.read()
1474n/a other.close()
1475n/a if not isinstance(text, str):
1476n/a text = text.decode('ascii')
1477n/a return self.name == other.name == text
1478n/a
1479n/a
1480n/aclass TestFileTypeR(TempDirMixin, ParserTestCase):
1481n/a """Test the FileType option/argument type for reading files"""
1482n/a
1483n/a def setUp(self):
1484n/a super(TestFileTypeR, self).setUp()
1485n/a for file_name in ['foo', 'bar']:
1486n/a file = open(os.path.join(self.temp_dir, file_name), 'w')
1487n/a file.write(file_name)
1488n/a file.close()
1489n/a self.create_readonly_file('readonly')
1490n/a
1491n/a argument_signatures = [
1492n/a Sig('-x', type=argparse.FileType()),
1493n/a Sig('spam', type=argparse.FileType('r')),
1494n/a ]
1495n/a failures = ['-x', '', 'non-existent-file.txt']
1496n/a successes = [
1497n/a ('foo', NS(x=None, spam=RFile('foo'))),
1498n/a ('-x foo bar', NS(x=RFile('foo'), spam=RFile('bar'))),
1499n/a ('bar -x foo', NS(x=RFile('foo'), spam=RFile('bar'))),
1500n/a ('-x - -', NS(x=sys.stdin, spam=sys.stdin)),
1501n/a ('readonly', NS(x=None, spam=RFile('readonly'))),
1502n/a ]
1503n/a
1504n/aclass TestFileTypeDefaults(TempDirMixin, ParserTestCase):
1505n/a """Test that a file is not created unless the default is needed"""
1506n/a def setUp(self):
1507n/a super(TestFileTypeDefaults, self).setUp()
1508n/a file = open(os.path.join(self.temp_dir, 'good'), 'w')
1509n/a file.write('good')
1510n/a file.close()
1511n/a
1512n/a argument_signatures = [
1513n/a Sig('-c', type=argparse.FileType('r'), default='no-file.txt'),
1514n/a ]
1515n/a # should provoke no such file error
1516n/a failures = ['']
1517n/a # should not provoke error because default file is created
1518n/a successes = [('-c good', NS(c=RFile('good')))]
1519n/a
1520n/a
1521n/aclass TestFileTypeRB(TempDirMixin, ParserTestCase):
1522n/a """Test the FileType option/argument type for reading files"""
1523n/a
1524n/a def setUp(self):
1525n/a super(TestFileTypeRB, self).setUp()
1526n/a for file_name in ['foo', 'bar']:
1527n/a file = open(os.path.join(self.temp_dir, file_name), 'w')
1528n/a file.write(file_name)
1529n/a file.close()
1530n/a
1531n/a argument_signatures = [
1532n/a Sig('-x', type=argparse.FileType('rb')),
1533n/a Sig('spam', type=argparse.FileType('rb')),
1534n/a ]
1535n/a failures = ['-x', '']
1536n/a successes = [
1537n/a ('foo', NS(x=None, spam=RFile('foo'))),
1538n/a ('-x foo bar', NS(x=RFile('foo'), spam=RFile('bar'))),
1539n/a ('bar -x foo', NS(x=RFile('foo'), spam=RFile('bar'))),
1540n/a ('-x - -', NS(x=sys.stdin, spam=sys.stdin)),
1541n/a ]
1542n/a
1543n/a
1544n/aclass WFile(object):
1545n/a seen = set()
1546n/a
1547n/a def __init__(self, name):
1548n/a self.name = name
1549n/a
1550n/a def __eq__(self, other):
1551n/a if other not in self.seen:
1552n/a text = 'Check that file is writable.'
1553n/a if 'b' in other.mode:
1554n/a text = text.encode('ascii')
1555n/a other.write(text)
1556n/a other.close()
1557n/a self.seen.add(other)
1558n/a return self.name == other.name
1559n/a
1560n/a
1561n/a@unittest.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0,
1562n/a "non-root user required")
1563n/aclass TestFileTypeW(TempDirMixin, ParserTestCase):
1564n/a """Test the FileType option/argument type for writing files"""
1565n/a
1566n/a def setUp(self):
1567n/a super(TestFileTypeW, self).setUp()
1568n/a self.create_readonly_file('readonly')
1569n/a
1570n/a argument_signatures = [
1571n/a Sig('-x', type=argparse.FileType('w')),
1572n/a Sig('spam', type=argparse.FileType('w')),
1573n/a ]
1574n/a failures = ['-x', '', 'readonly']
1575n/a successes = [
1576n/a ('foo', NS(x=None, spam=WFile('foo'))),
1577n/a ('-x foo bar', NS(x=WFile('foo'), spam=WFile('bar'))),
1578n/a ('bar -x foo', NS(x=WFile('foo'), spam=WFile('bar'))),
1579n/a ('-x - -', NS(x=sys.stdout, spam=sys.stdout)),
1580n/a ]
1581n/a
1582n/a
1583n/aclass TestFileTypeWB(TempDirMixin, ParserTestCase):
1584n/a
1585n/a argument_signatures = [
1586n/a Sig('-x', type=argparse.FileType('wb')),
1587n/a Sig('spam', type=argparse.FileType('wb')),
1588n/a ]
1589n/a failures = ['-x', '']
1590n/a successes = [
1591n/a ('foo', NS(x=None, spam=WFile('foo'))),
1592n/a ('-x foo bar', NS(x=WFile('foo'), spam=WFile('bar'))),
1593n/a ('bar -x foo', NS(x=WFile('foo'), spam=WFile('bar'))),
1594n/a ('-x - -', NS(x=sys.stdout, spam=sys.stdout)),
1595n/a ]
1596n/a
1597n/a
1598n/aclass TestFileTypeOpenArgs(TestCase):
1599n/a """Test that open (the builtin) is correctly called"""
1600n/a
1601n/a def test_open_args(self):
1602n/a FT = argparse.FileType
1603n/a cases = [
1604n/a (FT('rb'), ('rb', -1, None, None)),
1605n/a (FT('w', 1), ('w', 1, None, None)),
1606n/a (FT('w', errors='replace'), ('w', -1, None, 'replace')),
1607n/a (FT('wb', encoding='big5'), ('wb', -1, 'big5', None)),
1608n/a (FT('w', 0, 'l1', 'strict'), ('w', 0, 'l1', 'strict')),
1609n/a ]
1610n/a with mock.patch('builtins.open') as m:
1611n/a for type, args in cases:
1612n/a type('foo')
1613n/a m.assert_called_with('foo', *args)
1614n/a
1615n/a
1616n/aclass TestTypeCallable(ParserTestCase):
1617n/a """Test some callables as option/argument types"""
1618n/a
1619n/a argument_signatures = [
1620n/a Sig('--eggs', type=complex),
1621n/a Sig('spam', type=float),
1622n/a ]
1623n/a failures = ['a', '42j', '--eggs a', '--eggs 2i']
1624n/a successes = [
1625n/a ('--eggs=42 42', NS(eggs=42, spam=42.0)),
1626n/a ('--eggs 2j -- -1.5', NS(eggs=2j, spam=-1.5)),
1627n/a ('1024.675', NS(eggs=None, spam=1024.675)),
1628n/a ]
1629n/a
1630n/a
1631n/aclass TestTypeUserDefined(ParserTestCase):
1632n/a """Test a user-defined option/argument type"""
1633n/a
1634n/a class MyType(TestCase):
1635n/a
1636n/a def __init__(self, value):
1637n/a self.value = value
1638n/a
1639n/a def __eq__(self, other):
1640n/a return (type(self), self.value) == (type(other), other.value)
1641n/a
1642n/a argument_signatures = [
1643n/a Sig('-x', type=MyType),
1644n/a Sig('spam', type=MyType),
1645n/a ]
1646n/a failures = []
1647n/a successes = [
1648n/a ('a -x b', NS(x=MyType('b'), spam=MyType('a'))),
1649n/a ('-xf g', NS(x=MyType('f'), spam=MyType('g'))),
1650n/a ]
1651n/a
1652n/a
1653n/aclass TestTypeClassicClass(ParserTestCase):
1654n/a """Test a classic class type"""
1655n/a
1656n/a class C:
1657n/a
1658n/a def __init__(self, value):
1659n/a self.value = value
1660n/a
1661n/a def __eq__(self, other):
1662n/a return (type(self), self.value) == (type(other), other.value)
1663n/a
1664n/a argument_signatures = [
1665n/a Sig('-x', type=C),
1666n/a Sig('spam', type=C),
1667n/a ]
1668n/a failures = []
1669n/a successes = [
1670n/a ('a -x b', NS(x=C('b'), spam=C('a'))),
1671n/a ('-xf g', NS(x=C('f'), spam=C('g'))),
1672n/a ]
1673n/a
1674n/a
1675n/aclass TestTypeRegistration(TestCase):
1676n/a """Test a user-defined type by registering it"""
1677n/a
1678n/a def test(self):
1679n/a
1680n/a def get_my_type(string):
1681n/a return 'my_type{%s}' % string
1682n/a
1683n/a parser = argparse.ArgumentParser()
1684n/a parser.register('type', 'my_type', get_my_type)
1685n/a parser.add_argument('-x', type='my_type')
1686n/a parser.add_argument('y', type='my_type')
1687n/a
1688n/a self.assertEqual(parser.parse_args('1'.split()),
1689n/a NS(x=None, y='my_type{1}'))
1690n/a self.assertEqual(parser.parse_args('-x 1 42'.split()),
1691n/a NS(x='my_type{1}', y='my_type{42}'))
1692n/a
1693n/a
1694n/a# ============
1695n/a# Action tests
1696n/a# ============
1697n/a
1698n/aclass TestActionUserDefined(ParserTestCase):
1699n/a """Test a user-defined option/argument action"""
1700n/a
1701n/a class OptionalAction(argparse.Action):
1702n/a
1703n/a def __call__(self, parser, namespace, value, option_string=None):
1704n/a try:
1705n/a # check destination and option string
1706n/a assert self.dest == 'spam', 'dest: %s' % self.dest
1707n/a assert option_string == '-s', 'flag: %s' % option_string
1708n/a # when option is before argument, badger=2, and when
1709n/a # option is after argument, badger=<whatever was set>
1710n/a expected_ns = NS(spam=0.25)
1711n/a if value in [0.125, 0.625]:
1712n/a expected_ns.badger = 2
1713n/a elif value in [2.0]:
1714n/a expected_ns.badger = 84
1715n/a else:
1716n/a raise AssertionError('value: %s' % value)
1717n/a assert expected_ns == namespace, ('expected %s, got %s' %
1718n/a (expected_ns, namespace))
1719n/a except AssertionError:
1720n/a e = sys.exc_info()[1]
1721n/a raise ArgumentParserError('opt_action failed: %s' % e)
1722n/a setattr(namespace, 'spam', value)
1723n/a
1724n/a class PositionalAction(argparse.Action):
1725n/a
1726n/a def __call__(self, parser, namespace, value, option_string=None):
1727n/a try:
1728n/a assert option_string is None, ('option_string: %s' %
1729n/a option_string)
1730n/a # check destination
1731n/a assert self.dest == 'badger', 'dest: %s' % self.dest
1732n/a # when argument is before option, spam=0.25, and when
1733n/a # option is after argument, spam=<whatever was set>
1734n/a expected_ns = NS(badger=2)
1735n/a if value in [42, 84]:
1736n/a expected_ns.spam = 0.25
1737n/a elif value in [1]:
1738n/a expected_ns.spam = 0.625
1739n/a elif value in [2]:
1740n/a expected_ns.spam = 0.125
1741n/a else:
1742n/a raise AssertionError('value: %s' % value)
1743n/a assert expected_ns == namespace, ('expected %s, got %s' %
1744n/a (expected_ns, namespace))
1745n/a except AssertionError:
1746n/a e = sys.exc_info()[1]
1747n/a raise ArgumentParserError('arg_action failed: %s' % e)
1748n/a setattr(namespace, 'badger', value)
1749n/a
1750n/a argument_signatures = [
1751n/a Sig('-s', dest='spam', action=OptionalAction,
1752n/a type=float, default=0.25),
1753n/a Sig('badger', action=PositionalAction,
1754n/a type=int, nargs='?', default=2),
1755n/a ]
1756n/a failures = []
1757n/a successes = [
1758n/a ('-s0.125', NS(spam=0.125, badger=2)),
1759n/a ('42', NS(spam=0.25, badger=42)),
1760n/a ('-s 0.625 1', NS(spam=0.625, badger=1)),
1761n/a ('84 -s2', NS(spam=2.0, badger=84)),
1762n/a ]
1763n/a
1764n/a
1765n/aclass TestActionRegistration(TestCase):
1766n/a """Test a user-defined action supplied by registering it"""
1767n/a
1768n/a class MyAction(argparse.Action):
1769n/a
1770n/a def __call__(self, parser, namespace, values, option_string=None):
1771n/a setattr(namespace, self.dest, 'foo[%s]' % values)
1772n/a
1773n/a def test(self):
1774n/a
1775n/a parser = argparse.ArgumentParser()
1776n/a parser.register('action', 'my_action', self.MyAction)
1777n/a parser.add_argument('badger', action='my_action')
1778n/a
1779n/a self.assertEqual(parser.parse_args(['1']), NS(badger='foo[1]'))
1780n/a self.assertEqual(parser.parse_args(['42']), NS(badger='foo[42]'))
1781n/a
1782n/a
1783n/a# ================
1784n/a# Subparsers tests
1785n/a# ================
1786n/a
1787n/aclass TestAddSubparsers(TestCase):
1788n/a """Test the add_subparsers method"""
1789n/a
1790n/a def assertArgumentParserError(self, *args, **kwargs):
1791n/a self.assertRaises(ArgumentParserError, *args, **kwargs)
1792n/a
1793n/a def _get_parser(self, subparser_help=False, prefix_chars=None,
1794n/a aliases=False):
1795n/a # create a parser with a subparsers argument
1796n/a if prefix_chars:
1797n/a parser = ErrorRaisingArgumentParser(
1798n/a prog='PROG', description='main description', prefix_chars=prefix_chars)
1799n/a parser.add_argument(
1800n/a prefix_chars[0] * 2 + 'foo', action='store_true', help='foo help')
1801n/a else:
1802n/a parser = ErrorRaisingArgumentParser(
1803n/a prog='PROG', description='main description')
1804n/a parser.add_argument(
1805n/a '--foo', action='store_true', help='foo help')
1806n/a parser.add_argument(
1807n/a 'bar', type=float, help='bar help')
1808n/a
1809n/a # check that only one subparsers argument can be added
1810n/a subparsers_kwargs = {}
1811n/a if aliases:
1812n/a subparsers_kwargs['metavar'] = 'COMMAND'
1813n/a subparsers_kwargs['title'] = 'commands'
1814n/a else:
1815n/a subparsers_kwargs['help'] = 'command help'
1816n/a subparsers = parser.add_subparsers(**subparsers_kwargs)
1817n/a self.assertArgumentParserError(parser.add_subparsers)
1818n/a
1819n/a # add first sub-parser
1820n/a parser1_kwargs = dict(description='1 description')
1821n/a if subparser_help:
1822n/a parser1_kwargs['help'] = '1 help'
1823n/a if aliases:
1824n/a parser1_kwargs['aliases'] = ['1alias1', '1alias2']
1825n/a parser1 = subparsers.add_parser('1', **parser1_kwargs)
1826n/a parser1.add_argument('-w', type=int, help='w help')
1827n/a parser1.add_argument('x', choices='abc', help='x help')
1828n/a
1829n/a # add second sub-parser
1830n/a parser2_kwargs = dict(description='2 description')
1831n/a if subparser_help:
1832n/a parser2_kwargs['help'] = '2 help'
1833n/a parser2 = subparsers.add_parser('2', **parser2_kwargs)
1834n/a parser2.add_argument('-y', choices='123', help='y help')
1835n/a parser2.add_argument('z', type=complex, nargs='*', help='z help')
1836n/a
1837n/a # add third sub-parser
1838n/a parser3_kwargs = dict(description='3 description')
1839n/a if subparser_help:
1840n/a parser3_kwargs['help'] = '3 help'
1841n/a parser3 = subparsers.add_parser('3', **parser3_kwargs)
1842n/a parser3.add_argument('t', type=int, help='t help')
1843n/a parser3.add_argument('u', nargs='...', help='u help')
1844n/a
1845n/a # return the main parser
1846n/a return parser
1847n/a
1848n/a def setUp(self):
1849n/a super().setUp()
1850n/a self.parser = self._get_parser()
1851n/a self.command_help_parser = self._get_parser(subparser_help=True)
1852n/a
1853n/a def test_parse_args_failures(self):
1854n/a # check some failure cases:
1855n/a for args_str in ['', 'a', 'a a', '0.5 a', '0.5 1',
1856n/a '0.5 1 -y', '0.5 2 -w']:
1857n/a args = args_str.split()
1858n/a self.assertArgumentParserError(self.parser.parse_args, args)
1859n/a
1860n/a def test_parse_args(self):
1861n/a # check some non-failure cases:
1862n/a self.assertEqual(
1863n/a self.parser.parse_args('0.5 1 b -w 7'.split()),
1864n/a NS(foo=False, bar=0.5, w=7, x='b'),
1865n/a )
1866n/a self.assertEqual(
1867n/a self.parser.parse_args('0.25 --foo 2 -y 2 3j -- -1j'.split()),
1868n/a NS(foo=True, bar=0.25, y='2', z=[3j, -1j]),
1869n/a )
1870n/a self.assertEqual(
1871n/a self.parser.parse_args('--foo 0.125 1 c'.split()),
1872n/a NS(foo=True, bar=0.125, w=None, x='c'),
1873n/a )
1874n/a self.assertEqual(
1875n/a self.parser.parse_args('-1.5 3 11 -- a --foo 7 -- b'.split()),
1876n/a NS(foo=False, bar=-1.5, t=11, u=['a', '--foo', '7', '--', 'b']),
1877n/a )
1878n/a
1879n/a def test_parse_known_args(self):
1880n/a self.assertEqual(
1881n/a self.parser.parse_known_args('0.5 1 b -w 7'.split()),
1882n/a (NS(foo=False, bar=0.5, w=7, x='b'), []),
1883n/a )
1884n/a self.assertEqual(
1885n/a self.parser.parse_known_args('0.5 -p 1 b -w 7'.split()),
1886n/a (NS(foo=False, bar=0.5, w=7, x='b'), ['-p']),
1887n/a )
1888n/a self.assertEqual(
1889n/a self.parser.parse_known_args('0.5 1 b -w 7 -p'.split()),
1890n/a (NS(foo=False, bar=0.5, w=7, x='b'), ['-p']),
1891n/a )
1892n/a self.assertEqual(
1893n/a self.parser.parse_known_args('0.5 1 b -q -rs -w 7'.split()),
1894n/a (NS(foo=False, bar=0.5, w=7, x='b'), ['-q', '-rs']),
1895n/a )
1896n/a self.assertEqual(
1897n/a self.parser.parse_known_args('0.5 -W 1 b -X Y -w 7 Z'.split()),
1898n/a (NS(foo=False, bar=0.5, w=7, x='b'), ['-W', '-X', 'Y', 'Z']),
1899n/a )
1900n/a
1901n/a def test_dest(self):
1902n/a parser = ErrorRaisingArgumentParser()
1903n/a parser.add_argument('--foo', action='store_true')
1904n/a subparsers = parser.add_subparsers(dest='bar')
1905n/a parser1 = subparsers.add_parser('1')
1906n/a parser1.add_argument('baz')
1907n/a self.assertEqual(NS(foo=False, bar='1', baz='2'),
1908n/a parser.parse_args('1 2'.split()))
1909n/a
1910n/a def test_help(self):
1911n/a self.assertEqual(self.parser.format_usage(),
1912n/a 'usage: PROG [-h] [--foo] bar {1,2,3} ...\n')
1913n/a self.assertEqual(self.parser.format_help(), textwrap.dedent('''\
1914n/a usage: PROG [-h] [--foo] bar {1,2,3} ...
1915n/a
1916n/a main description
1917n/a
1918n/a positional arguments:
1919n/a bar bar help
1920n/a {1,2,3} command help
1921n/a
1922n/a optional arguments:
1923n/a -h, --help show this help message and exit
1924n/a --foo foo help
1925n/a '''))
1926n/a
1927n/a def test_help_extra_prefix_chars(self):
1928n/a # Make sure - is still used for help if it is a non-first prefix char
1929n/a parser = self._get_parser(prefix_chars='+:-')
1930n/a self.assertEqual(parser.format_usage(),
1931n/a 'usage: PROG [-h] [++foo] bar {1,2,3} ...\n')
1932n/a self.assertEqual(parser.format_help(), textwrap.dedent('''\
1933n/a usage: PROG [-h] [++foo] bar {1,2,3} ...
1934n/a
1935n/a main description
1936n/a
1937n/a positional arguments:
1938n/a bar bar help
1939n/a {1,2,3} command help
1940n/a
1941n/a optional arguments:
1942n/a -h, --help show this help message and exit
1943n/a ++foo foo help
1944n/a '''))
1945n/a
1946n/a def test_help_non_breaking_spaces(self):
1947n/a parser = ErrorRaisingArgumentParser(
1948n/a prog='PROG', description='main description')
1949n/a parser.add_argument(
1950n/a "--non-breaking", action='store_false',
1951n/a help='help message containing non-breaking spaces shall not '
1952n/a 'wrap\N{NO-BREAK SPACE}at non-breaking spaces')
1953n/a self.assertEqual(parser.format_help(), textwrap.dedent('''\
1954n/a usage: PROG [-h] [--non-breaking]
1955n/a
1956n/a main description
1957n/a
1958n/a optional arguments:
1959n/a -h, --help show this help message and exit
1960n/a --non-breaking help message containing non-breaking spaces shall not
1961n/a wrap\N{NO-BREAK SPACE}at non-breaking spaces
1962n/a '''))
1963n/a
1964n/a def test_help_alternate_prefix_chars(self):
1965n/a parser = self._get_parser(prefix_chars='+:/')
1966n/a self.assertEqual(parser.format_usage(),
1967n/a 'usage: PROG [+h] [++foo] bar {1,2,3} ...\n')
1968n/a self.assertEqual(parser.format_help(), textwrap.dedent('''\
1969n/a usage: PROG [+h] [++foo] bar {1,2,3} ...
1970n/a
1971n/a main description
1972n/a
1973n/a positional arguments:
1974n/a bar bar help
1975n/a {1,2,3} command help
1976n/a
1977n/a optional arguments:
1978n/a +h, ++help show this help message and exit
1979n/a ++foo foo help
1980n/a '''))
1981n/a
1982n/a def test_parser_command_help(self):
1983n/a self.assertEqual(self.command_help_parser.format_usage(),
1984n/a 'usage: PROG [-h] [--foo] bar {1,2,3} ...\n')
1985n/a self.assertEqual(self.command_help_parser.format_help(),
1986n/a textwrap.dedent('''\
1987n/a usage: PROG [-h] [--foo] bar {1,2,3} ...
1988n/a
1989n/a main description
1990n/a
1991n/a positional arguments:
1992n/a bar bar help
1993n/a {1,2,3} command help
1994n/a 1 1 help
1995n/a 2 2 help
1996n/a 3 3 help
1997n/a
1998n/a optional arguments:
1999n/a -h, --help show this help message and exit
2000n/a --foo foo help
2001n/a '''))
2002n/a
2003n/a def test_subparser_title_help(self):
2004n/a parser = ErrorRaisingArgumentParser(prog='PROG',
2005n/a description='main description')
2006n/a parser.add_argument('--foo', action='store_true', help='foo help')
2007n/a parser.add_argument('bar', help='bar help')
2008n/a subparsers = parser.add_subparsers(title='subcommands',
2009n/a description='command help',
2010n/a help='additional text')
2011n/a parser1 = subparsers.add_parser('1')
2012n/a parser2 = subparsers.add_parser('2')
2013n/a self.assertEqual(parser.format_usage(),
2014n/a 'usage: PROG [-h] [--foo] bar {1,2} ...\n')
2015n/a self.assertEqual(parser.format_help(), textwrap.dedent('''\
2016n/a usage: PROG [-h] [--foo] bar {1,2} ...
2017n/a
2018n/a main description
2019n/a
2020n/a positional arguments:
2021n/a bar bar help
2022n/a
2023n/a optional arguments:
2024n/a -h, --help show this help message and exit
2025n/a --foo foo help
2026n/a
2027n/a subcommands:
2028n/a command help
2029n/a
2030n/a {1,2} additional text
2031n/a '''))
2032n/a
2033n/a def _test_subparser_help(self, args_str, expected_help):
2034n/a with self.assertRaises(ArgumentParserError) as cm:
2035n/a self.parser.parse_args(args_str.split())
2036n/a self.assertEqual(expected_help, cm.exception.stdout)
2037n/a
2038n/a def test_subparser1_help(self):
2039n/a self._test_subparser_help('5.0 1 -h', textwrap.dedent('''\
2040n/a usage: PROG bar 1 [-h] [-w W] {a,b,c}
2041n/a
2042n/a 1 description
2043n/a
2044n/a positional arguments:
2045n/a {a,b,c} x help
2046n/a
2047n/a optional arguments:
2048n/a -h, --help show this help message and exit
2049n/a -w W w help
2050n/a '''))
2051n/a
2052n/a def test_subparser2_help(self):
2053n/a self._test_subparser_help('5.0 2 -h', textwrap.dedent('''\
2054n/a usage: PROG bar 2 [-h] [-y {1,2,3}] [z [z ...]]
2055n/a
2056n/a 2 description
2057n/a
2058n/a positional arguments:
2059n/a z z help
2060n/a
2061n/a optional arguments:
2062n/a -h, --help show this help message and exit
2063n/a -y {1,2,3} y help
2064n/a '''))
2065n/a
2066n/a def test_alias_invocation(self):
2067n/a parser = self._get_parser(aliases=True)
2068n/a self.assertEqual(
2069n/a parser.parse_known_args('0.5 1alias1 b'.split()),
2070n/a (NS(foo=False, bar=0.5, w=None, x='b'), []),
2071n/a )
2072n/a self.assertEqual(
2073n/a parser.parse_known_args('0.5 1alias2 b'.split()),
2074n/a (NS(foo=False, bar=0.5, w=None, x='b'), []),
2075n/a )
2076n/a
2077n/a def test_error_alias_invocation(self):
2078n/a parser = self._get_parser(aliases=True)
2079n/a self.assertArgumentParserError(parser.parse_args,
2080n/a '0.5 1alias3 b'.split())
2081n/a
2082n/a def test_alias_help(self):
2083n/a parser = self._get_parser(aliases=True, subparser_help=True)
2084n/a self.maxDiff = None
2085n/a self.assertEqual(parser.format_help(), textwrap.dedent("""\
2086n/a usage: PROG [-h] [--foo] bar COMMAND ...
2087n/a
2088n/a main description
2089n/a
2090n/a positional arguments:
2091n/a bar bar help
2092n/a
2093n/a optional arguments:
2094n/a -h, --help show this help message and exit
2095n/a --foo foo help
2096n/a
2097n/a commands:
2098n/a COMMAND
2099n/a 1 (1alias1, 1alias2)
2100n/a 1 help
2101n/a 2 2 help
2102n/a 3 3 help
2103n/a """))
2104n/a
2105n/a# ============
2106n/a# Groups tests
2107n/a# ============
2108n/a
2109n/aclass TestPositionalsGroups(TestCase):
2110n/a """Tests that order of group positionals matches construction order"""
2111n/a
2112n/a def test_nongroup_first(self):
2113n/a parser = ErrorRaisingArgumentParser()
2114n/a parser.add_argument('foo')
2115n/a group = parser.add_argument_group('g')
2116n/a group.add_argument('bar')
2117n/a parser.add_argument('baz')
2118n/a expected = NS(foo='1', bar='2', baz='3')
2119n/a result = parser.parse_args('1 2 3'.split())
2120n/a self.assertEqual(expected, result)
2121n/a
2122n/a def test_group_first(self):
2123n/a parser = ErrorRaisingArgumentParser()
2124n/a group = parser.add_argument_group('xxx')
2125n/a group.add_argument('foo')
2126n/a parser.add_argument('bar')
2127n/a parser.add_argument('baz')
2128n/a expected = NS(foo='1', bar='2', baz='3')
2129n/a result = parser.parse_args('1 2 3'.split())
2130n/a self.assertEqual(expected, result)
2131n/a
2132n/a def test_interleaved_groups(self):
2133n/a parser = ErrorRaisingArgumentParser()
2134n/a group = parser.add_argument_group('xxx')
2135n/a parser.add_argument('foo')
2136n/a group.add_argument('bar')
2137n/a parser.add_argument('baz')
2138n/a group = parser.add_argument_group('yyy')
2139n/a group.add_argument('frell')
2140n/a expected = NS(foo='1', bar='2', baz='3', frell='4')
2141n/a result = parser.parse_args('1 2 3 4'.split())
2142n/a self.assertEqual(expected, result)
2143n/a
2144n/a# ===================
2145n/a# Parent parser tests
2146n/a# ===================
2147n/a
2148n/aclass TestParentParsers(TestCase):
2149n/a """Tests that parsers can be created with parent parsers"""
2150n/a
2151n/a def assertArgumentParserError(self, *args, **kwargs):
2152n/a self.assertRaises(ArgumentParserError, *args, **kwargs)
2153n/a
2154n/a def setUp(self):
2155n/a super().setUp()
2156n/a self.wxyz_parent = ErrorRaisingArgumentParser(add_help=False)
2157n/a self.wxyz_parent.add_argument('--w')
2158n/a x_group = self.wxyz_parent.add_argument_group('x')
2159n/a x_group.add_argument('-y')
2160n/a self.wxyz_parent.add_argument('z')
2161n/a
2162n/a self.abcd_parent = ErrorRaisingArgumentParser(add_help=False)
2163n/a self.abcd_parent.add_argument('a')
2164n/a self.abcd_parent.add_argument('-b')
2165n/a c_group = self.abcd_parent.add_argument_group('c')
2166n/a c_group.add_argument('--d')
2167n/a
2168n/a self.w_parent = ErrorRaisingArgumentParser(add_help=False)
2169n/a self.w_parent.add_argument('--w')
2170n/a
2171n/a self.z_parent = ErrorRaisingArgumentParser(add_help=False)
2172n/a self.z_parent.add_argument('z')
2173n/a
2174n/a # parents with mutually exclusive groups
2175n/a self.ab_mutex_parent = ErrorRaisingArgumentParser(add_help=False)
2176n/a group = self.ab_mutex_parent.add_mutually_exclusive_group()
2177n/a group.add_argument('-a', action='store_true')
2178n/a group.add_argument('-b', action='store_true')
2179n/a
2180n/a self.main_program = os.path.basename(sys.argv[0])
2181n/a
2182n/a def test_single_parent(self):
2183n/a parser = ErrorRaisingArgumentParser(parents=[self.wxyz_parent])
2184n/a self.assertEqual(parser.parse_args('-y 1 2 --w 3'.split()),
2185n/a NS(w='3', y='1', z='2'))
2186n/a
2187n/a def test_single_parent_mutex(self):
2188n/a self._test_mutex_ab(self.ab_mutex_parent.parse_args)
2189n/a parser = ErrorRaisingArgumentParser(parents=[self.ab_mutex_parent])
2190n/a self._test_mutex_ab(parser.parse_args)
2191n/a
2192n/a def test_single_granparent_mutex(self):
2193n/a parents = [self.ab_mutex_parent]
2194n/a parser = ErrorRaisingArgumentParser(add_help=False, parents=parents)
2195n/a parser = ErrorRaisingArgumentParser(parents=[parser])
2196n/a self._test_mutex_ab(parser.parse_args)
2197n/a
2198n/a def _test_mutex_ab(self, parse_args):
2199n/a self.assertEqual(parse_args([]), NS(a=False, b=False))
2200n/a self.assertEqual(parse_args(['-a']), NS(a=True, b=False))
2201n/a self.assertEqual(parse_args(['-b']), NS(a=False, b=True))
2202n/a self.assertArgumentParserError(parse_args, ['-a', '-b'])
2203n/a self.assertArgumentParserError(parse_args, ['-b', '-a'])
2204n/a self.assertArgumentParserError(parse_args, ['-c'])
2205n/a self.assertArgumentParserError(parse_args, ['-a', '-c'])
2206n/a self.assertArgumentParserError(parse_args, ['-b', '-c'])
2207n/a
2208n/a def test_multiple_parents(self):
2209n/a parents = [self.abcd_parent, self.wxyz_parent]
2210n/a parser = ErrorRaisingArgumentParser(parents=parents)
2211n/a self.assertEqual(parser.parse_args('--d 1 --w 2 3 4'.split()),
2212n/a NS(a='3', b=None, d='1', w='2', y=None, z='4'))
2213n/a
2214n/a def test_multiple_parents_mutex(self):
2215n/a parents = [self.ab_mutex_parent, self.wxyz_parent]
2216n/a parser = ErrorRaisingArgumentParser(parents=parents)
2217n/a self.assertEqual(parser.parse_args('-a --w 2 3'.split()),
2218n/a NS(a=True, b=False, w='2', y=None, z='3'))
2219n/a self.assertArgumentParserError(
2220n/a parser.parse_args, '-a --w 2 3 -b'.split())
2221n/a self.assertArgumentParserError(
2222n/a parser.parse_args, '-a -b --w 2 3'.split())
2223n/a
2224n/a def test_conflicting_parents(self):
2225n/a self.assertRaises(
2226n/a argparse.ArgumentError,
2227n/a argparse.ArgumentParser,
2228n/a parents=[self.w_parent, self.wxyz_parent])
2229n/a
2230n/a def test_conflicting_parents_mutex(self):
2231n/a self.assertRaises(
2232n/a argparse.ArgumentError,
2233n/a argparse.ArgumentParser,
2234n/a parents=[self.abcd_parent, self.ab_mutex_parent])
2235n/a
2236n/a def test_same_argument_name_parents(self):
2237n/a parents = [self.wxyz_parent, self.z_parent]
2238n/a parser = ErrorRaisingArgumentParser(parents=parents)
2239n/a self.assertEqual(parser.parse_args('1 2'.split()),
2240n/a NS(w=None, y=None, z='2'))
2241n/a
2242n/a def test_subparser_parents(self):
2243n/a parser = ErrorRaisingArgumentParser()
2244n/a subparsers = parser.add_subparsers()
2245n/a abcde_parser = subparsers.add_parser('bar', parents=[self.abcd_parent])
2246n/a abcde_parser.add_argument('e')
2247n/a self.assertEqual(parser.parse_args('bar -b 1 --d 2 3 4'.split()),
2248n/a NS(a='3', b='1', d='2', e='4'))
2249n/a
2250n/a def test_subparser_parents_mutex(self):
2251n/a parser = ErrorRaisingArgumentParser()
2252n/a subparsers = parser.add_subparsers()
2253n/a parents = [self.ab_mutex_parent]
2254n/a abc_parser = subparsers.add_parser('foo', parents=parents)
2255n/a c_group = abc_parser.add_argument_group('c_group')
2256n/a c_group.add_argument('c')
2257n/a parents = [self.wxyz_parent, self.ab_mutex_parent]
2258n/a wxyzabe_parser = subparsers.add_parser('bar', parents=parents)
2259n/a wxyzabe_parser.add_argument('e')
2260n/a self.assertEqual(parser.parse_args('foo -a 4'.split()),
2261n/a NS(a=True, b=False, c='4'))
2262n/a self.assertEqual(parser.parse_args('bar -b --w 2 3 4'.split()),
2263n/a NS(a=False, b=True, w='2', y=None, z='3', e='4'))
2264n/a self.assertArgumentParserError(
2265n/a parser.parse_args, 'foo -a -b 4'.split())
2266n/a self.assertArgumentParserError(
2267n/a parser.parse_args, 'bar -b -a 4'.split())
2268n/a
2269n/a def test_parent_help(self):
2270n/a parents = [self.abcd_parent, self.wxyz_parent]
2271n/a parser = ErrorRaisingArgumentParser(parents=parents)
2272n/a parser_help = parser.format_help()
2273n/a progname = self.main_program
2274n/a self.assertEqual(parser_help, textwrap.dedent('''\
2275n/a usage: {}{}[-h] [-b B] [--d D] [--w W] [-y Y] a z
2276n/a
2277n/a positional arguments:
2278n/a a
2279n/a z
2280n/a
2281n/a optional arguments:
2282n/a -h, --help show this help message and exit
2283n/a -b B
2284n/a --w W
2285n/a
2286n/a c:
2287n/a --d D
2288n/a
2289n/a x:
2290n/a -y Y
2291n/a '''.format(progname, ' ' if progname else '' )))
2292n/a
2293n/a def test_groups_parents(self):
2294n/a parent = ErrorRaisingArgumentParser(add_help=False)
2295n/a g = parent.add_argument_group(title='g', description='gd')
2296n/a g.add_argument('-w')
2297n/a g.add_argument('-x')
2298n/a m = parent.add_mutually_exclusive_group()
2299n/a m.add_argument('-y')
2300n/a m.add_argument('-z')
2301n/a parser = ErrorRaisingArgumentParser(parents=[parent])
2302n/a
2303n/a self.assertRaises(ArgumentParserError, parser.parse_args,
2304n/a ['-y', 'Y', '-z', 'Z'])
2305n/a
2306n/a parser_help = parser.format_help()
2307n/a progname = self.main_program
2308n/a self.assertEqual(parser_help, textwrap.dedent('''\
2309n/a usage: {}{}[-h] [-w W] [-x X] [-y Y | -z Z]
2310n/a
2311n/a optional arguments:
2312n/a -h, --help show this help message and exit
2313n/a -y Y
2314n/a -z Z
2315n/a
2316n/a g:
2317n/a gd
2318n/a
2319n/a -w W
2320n/a -x X
2321n/a '''.format(progname, ' ' if progname else '' )))
2322n/a
2323n/a# ==============================
2324n/a# Mutually exclusive group tests
2325n/a# ==============================
2326n/a
2327n/aclass TestMutuallyExclusiveGroupErrors(TestCase):
2328n/a
2329n/a def test_invalid_add_argument_group(self):
2330n/a parser = ErrorRaisingArgumentParser()
2331n/a raises = self.assertRaises
2332n/a raises(TypeError, parser.add_mutually_exclusive_group, title='foo')
2333n/a
2334n/a def test_invalid_add_argument(self):
2335n/a parser = ErrorRaisingArgumentParser()
2336n/a group = parser.add_mutually_exclusive_group()
2337n/a add_argument = group.add_argument
2338n/a raises = self.assertRaises
2339n/a raises(ValueError, add_argument, '--foo', required=True)
2340n/a raises(ValueError, add_argument, 'bar')
2341n/a raises(ValueError, add_argument, 'bar', nargs='+')
2342n/a raises(ValueError, add_argument, 'bar', nargs=1)
2343n/a raises(ValueError, add_argument, 'bar', nargs=argparse.PARSER)
2344n/a
2345n/a def test_help(self):
2346n/a parser = ErrorRaisingArgumentParser(prog='PROG')
2347n/a group1 = parser.add_mutually_exclusive_group()
2348n/a group1.add_argument('--foo', action='store_true')
2349n/a group1.add_argument('--bar', action='store_false')
2350n/a group2 = parser.add_mutually_exclusive_group()
2351n/a group2.add_argument('--soup', action='store_true')
2352n/a group2.add_argument('--nuts', action='store_false')
2353n/a expected = '''\
2354n/a usage: PROG [-h] [--foo | --bar] [--soup | --nuts]
2355n/a
2356n/a optional arguments:
2357n/a -h, --help show this help message and exit
2358n/a --foo
2359n/a --bar
2360n/a --soup
2361n/a --nuts
2362n/a '''
2363n/a self.assertEqual(parser.format_help(), textwrap.dedent(expected))
2364n/a
2365n/aclass MEMixin(object):
2366n/a
2367n/a def test_failures_when_not_required(self):
2368n/a parse_args = self.get_parser(required=False).parse_args
2369n/a error = ArgumentParserError
2370n/a for args_string in self.failures:
2371n/a self.assertRaises(error, parse_args, args_string.split())
2372n/a
2373n/a def test_failures_when_required(self):
2374n/a parse_args = self.get_parser(required=True).parse_args
2375n/a error = ArgumentParserError
2376n/a for args_string in self.failures + ['']:
2377n/a self.assertRaises(error, parse_args, args_string.split())
2378n/a
2379n/a def test_successes_when_not_required(self):
2380n/a parse_args = self.get_parser(required=False).parse_args
2381n/a successes = self.successes + self.successes_when_not_required
2382n/a for args_string, expected_ns in successes:
2383n/a actual_ns = parse_args(args_string.split())
2384n/a self.assertEqual(actual_ns, expected_ns)
2385n/a
2386n/a def test_successes_when_required(self):
2387n/a parse_args = self.get_parser(required=True).parse_args
2388n/a for args_string, expected_ns in self.successes:
2389n/a actual_ns = parse_args(args_string.split())
2390n/a self.assertEqual(actual_ns, expected_ns)
2391n/a
2392n/a def test_usage_when_not_required(self):
2393n/a format_usage = self.get_parser(required=False).format_usage
2394n/a expected_usage = self.usage_when_not_required
2395n/a self.assertEqual(format_usage(), textwrap.dedent(expected_usage))
2396n/a
2397n/a def test_usage_when_required(self):
2398n/a format_usage = self.get_parser(required=True).format_usage
2399n/a expected_usage = self.usage_when_required
2400n/a self.assertEqual(format_usage(), textwrap.dedent(expected_usage))
2401n/a
2402n/a def test_help_when_not_required(self):
2403n/a format_help = self.get_parser(required=False).format_help
2404n/a help = self.usage_when_not_required + self.help
2405n/a self.assertEqual(format_help(), textwrap.dedent(help))
2406n/a
2407n/a def test_help_when_required(self):
2408n/a format_help = self.get_parser(required=True).format_help
2409n/a help = self.usage_when_required + self.help
2410n/a self.assertEqual(format_help(), textwrap.dedent(help))
2411n/a
2412n/a
2413n/aclass TestMutuallyExclusiveSimple(MEMixin, TestCase):
2414n/a
2415n/a def get_parser(self, required=None):
2416n/a parser = ErrorRaisingArgumentParser(prog='PROG')
2417n/a group = parser.add_mutually_exclusive_group(required=required)
2418n/a group.add_argument('--bar', help='bar help')
2419n/a group.add_argument('--baz', nargs='?', const='Z', help='baz help')
2420n/a return parser
2421n/a
2422n/a failures = ['--bar X --baz Y', '--bar X --baz']
2423n/a successes = [
2424n/a ('--bar X', NS(bar='X', baz=None)),
2425n/a ('--bar X --bar Z', NS(bar='Z', baz=None)),
2426n/a ('--baz Y', NS(bar=None, baz='Y')),
2427n/a ('--baz', NS(bar=None, baz='Z')),
2428n/a ]
2429n/a successes_when_not_required = [
2430n/a ('', NS(bar=None, baz=None)),
2431n/a ]
2432n/a
2433n/a usage_when_not_required = '''\
2434n/a usage: PROG [-h] [--bar BAR | --baz [BAZ]]
2435n/a '''
2436n/a usage_when_required = '''\
2437n/a usage: PROG [-h] (--bar BAR | --baz [BAZ])
2438n/a '''
2439n/a help = '''\
2440n/a
2441n/a optional arguments:
2442n/a -h, --help show this help message and exit
2443n/a --bar BAR bar help
2444n/a --baz [BAZ] baz help
2445n/a '''
2446n/a
2447n/a
2448n/aclass TestMutuallyExclusiveLong(MEMixin, TestCase):
2449n/a
2450n/a def get_parser(self, required=None):
2451n/a parser = ErrorRaisingArgumentParser(prog='PROG')
2452n/a parser.add_argument('--abcde', help='abcde help')
2453n/a parser.add_argument('--fghij', help='fghij help')
2454n/a group = parser.add_mutually_exclusive_group(required=required)
2455n/a group.add_argument('--klmno', help='klmno help')
2456n/a group.add_argument('--pqrst', help='pqrst help')
2457n/a return parser
2458n/a
2459n/a failures = ['--klmno X --pqrst Y']
2460n/a successes = [
2461n/a ('--klmno X', NS(abcde=None, fghij=None, klmno='X', pqrst=None)),
2462n/a ('--abcde Y --klmno X',
2463n/a NS(abcde='Y', fghij=None, klmno='X', pqrst=None)),
2464n/a ('--pqrst X', NS(abcde=None, fghij=None, klmno=None, pqrst='X')),
2465n/a ('--pqrst X --fghij Y',
2466n/a NS(abcde=None, fghij='Y', klmno=None, pqrst='X')),
2467n/a ]
2468n/a successes_when_not_required = [
2469n/a ('', NS(abcde=None, fghij=None, klmno=None, pqrst=None)),
2470n/a ]
2471n/a
2472n/a usage_when_not_required = '''\
2473n/a usage: PROG [-h] [--abcde ABCDE] [--fghij FGHIJ]
2474n/a [--klmno KLMNO | --pqrst PQRST]
2475n/a '''
2476n/a usage_when_required = '''\
2477n/a usage: PROG [-h] [--abcde ABCDE] [--fghij FGHIJ]
2478n/a (--klmno KLMNO | --pqrst PQRST)
2479n/a '''
2480n/a help = '''\
2481n/a
2482n/a optional arguments:
2483n/a -h, --help show this help message and exit
2484n/a --abcde ABCDE abcde help
2485n/a --fghij FGHIJ fghij help
2486n/a --klmno KLMNO klmno help
2487n/a --pqrst PQRST pqrst help
2488n/a '''
2489n/a
2490n/a
2491n/aclass TestMutuallyExclusiveFirstSuppressed(MEMixin, TestCase):
2492n/a
2493n/a def get_parser(self, required):
2494n/a parser = ErrorRaisingArgumentParser(prog='PROG')
2495n/a group = parser.add_mutually_exclusive_group(required=required)
2496n/a group.add_argument('-x', help=argparse.SUPPRESS)
2497n/a group.add_argument('-y', action='store_false', help='y help')
2498n/a return parser
2499n/a
2500n/a failures = ['-x X -y']
2501n/a successes = [
2502n/a ('-x X', NS(x='X', y=True)),
2503n/a ('-x X -x Y', NS(x='Y', y=True)),
2504n/a ('-y', NS(x=None, y=False)),
2505n/a ]
2506n/a successes_when_not_required = [
2507n/a ('', NS(x=None, y=True)),
2508n/a ]
2509n/a
2510n/a usage_when_not_required = '''\
2511n/a usage: PROG [-h] [-y]
2512n/a '''
2513n/a usage_when_required = '''\
2514n/a usage: PROG [-h] -y
2515n/a '''
2516n/a help = '''\
2517n/a
2518n/a optional arguments:
2519n/a -h, --help show this help message and exit
2520n/a -y y help
2521n/a '''
2522n/a
2523n/a
2524n/aclass TestMutuallyExclusiveManySuppressed(MEMixin, TestCase):
2525n/a
2526n/a def get_parser(self, required):
2527n/a parser = ErrorRaisingArgumentParser(prog='PROG')
2528n/a group = parser.add_mutually_exclusive_group(required=required)
2529n/a add = group.add_argument
2530n/a add('--spam', action='store_true', help=argparse.SUPPRESS)
2531n/a add('--badger', action='store_false', help=argparse.SUPPRESS)
2532n/a add('--bladder', help=argparse.SUPPRESS)
2533n/a return parser
2534n/a
2535n/a failures = [
2536n/a '--spam --badger',
2537n/a '--badger --bladder B',
2538n/a '--bladder B --spam',
2539n/a ]
2540n/a successes = [
2541n/a ('--spam', NS(spam=True, badger=True, bladder=None)),
2542n/a ('--badger', NS(spam=False, badger=False, bladder=None)),
2543n/a ('--bladder B', NS(spam=False, badger=True, bladder='B')),
2544n/a ('--spam --spam', NS(spam=True, badger=True, bladder=None)),
2545n/a ]
2546n/a successes_when_not_required = [
2547n/a ('', NS(spam=False, badger=True, bladder=None)),
2548n/a ]
2549n/a
2550n/a usage_when_required = usage_when_not_required = '''\
2551n/a usage: PROG [-h]
2552n/a '''
2553n/a help = '''\
2554n/a
2555n/a optional arguments:
2556n/a -h, --help show this help message and exit
2557n/a '''
2558n/a
2559n/a
2560n/aclass TestMutuallyExclusiveOptionalAndPositional(MEMixin, TestCase):
2561n/a
2562n/a def get_parser(self, required):
2563n/a parser = ErrorRaisingArgumentParser(prog='PROG')
2564n/a group = parser.add_mutually_exclusive_group(required=required)
2565n/a group.add_argument('--foo', action='store_true', help='FOO')
2566n/a group.add_argument('--spam', help='SPAM')
2567n/a group.add_argument('badger', nargs='*', default='X', help='BADGER')
2568n/a return parser
2569n/a
2570n/a failures = [
2571n/a '--foo --spam S',
2572n/a '--spam S X',
2573n/a 'X --foo',
2574n/a 'X Y Z --spam S',
2575n/a '--foo X Y',
2576n/a ]
2577n/a successes = [
2578n/a ('--foo', NS(foo=True, spam=None, badger='X')),
2579n/a ('--spam S', NS(foo=False, spam='S', badger='X')),
2580n/a ('X', NS(foo=False, spam=None, badger=['X'])),
2581n/a ('X Y Z', NS(foo=False, spam=None, badger=['X', 'Y', 'Z'])),
2582n/a ]
2583n/a successes_when_not_required = [
2584n/a ('', NS(foo=False, spam=None, badger='X')),
2585n/a ]
2586n/a
2587n/a usage_when_not_required = '''\
2588n/a usage: PROG [-h] [--foo | --spam SPAM | badger [badger ...]]
2589n/a '''
2590n/a usage_when_required = '''\
2591n/a usage: PROG [-h] (--foo | --spam SPAM | badger [badger ...])
2592n/a '''
2593n/a help = '''\
2594n/a
2595n/a positional arguments:
2596n/a badger BADGER
2597n/a
2598n/a optional arguments:
2599n/a -h, --help show this help message and exit
2600n/a --foo FOO
2601n/a --spam SPAM SPAM
2602n/a '''
2603n/a
2604n/a
2605n/aclass TestMutuallyExclusiveOptionalsMixed(MEMixin, TestCase):
2606n/a
2607n/a def get_parser(self, required):
2608n/a parser = ErrorRaisingArgumentParser(prog='PROG')
2609n/a parser.add_argument('-x', action='store_true', help='x help')
2610n/a group = parser.add_mutually_exclusive_group(required=required)
2611n/a group.add_argument('-a', action='store_true', help='a help')
2612n/a group.add_argument('-b', action='store_true', help='b help')
2613n/a parser.add_argument('-y', action='store_true', help='y help')
2614n/a group.add_argument('-c', action='store_true', help='c help')
2615n/a return parser
2616n/a
2617n/a failures = ['-a -b', '-b -c', '-a -c', '-a -b -c']
2618n/a successes = [
2619n/a ('-a', NS(a=True, b=False, c=False, x=False, y=False)),
2620n/a ('-b', NS(a=False, b=True, c=False, x=False, y=False)),
2621n/a ('-c', NS(a=False, b=False, c=True, x=False, y=False)),
2622n/a ('-a -x', NS(a=True, b=False, c=False, x=True, y=False)),
2623n/a ('-y -b', NS(a=False, b=True, c=False, x=False, y=True)),
2624n/a ('-x -y -c', NS(a=False, b=False, c=True, x=True, y=True)),
2625n/a ]
2626n/a successes_when_not_required = [
2627n/a ('', NS(a=False, b=False, c=False, x=False, y=False)),
2628n/a ('-x', NS(a=False, b=False, c=False, x=True, y=False)),
2629n/a ('-y', NS(a=False, b=False, c=False, x=False, y=True)),
2630n/a ]
2631n/a
2632n/a usage_when_required = usage_when_not_required = '''\
2633n/a usage: PROG [-h] [-x] [-a] [-b] [-y] [-c]
2634n/a '''
2635n/a help = '''\
2636n/a
2637n/a optional arguments:
2638n/a -h, --help show this help message and exit
2639n/a -x x help
2640n/a -a a help
2641n/a -b b help
2642n/a -y y help
2643n/a -c c help
2644n/a '''
2645n/a
2646n/a
2647n/aclass TestMutuallyExclusiveInGroup(MEMixin, TestCase):
2648n/a
2649n/a def get_parser(self, required=None):
2650n/a parser = ErrorRaisingArgumentParser(prog='PROG')
2651n/a titled_group = parser.add_argument_group(
2652n/a title='Titled group', description='Group description')
2653n/a mutex_group = \
2654n/a titled_group.add_mutually_exclusive_group(required=required)
2655n/a mutex_group.add_argument('--bar', help='bar help')
2656n/a mutex_group.add_argument('--baz', help='baz help')
2657n/a return parser
2658n/a
2659n/a failures = ['--bar X --baz Y', '--baz X --bar Y']
2660n/a successes = [
2661n/a ('--bar X', NS(bar='X', baz=None)),
2662n/a ('--baz Y', NS(bar=None, baz='Y')),
2663n/a ]
2664n/a successes_when_not_required = [
2665n/a ('', NS(bar=None, baz=None)),
2666n/a ]
2667n/a
2668n/a usage_when_not_required = '''\
2669n/a usage: PROG [-h] [--bar BAR | --baz BAZ]
2670n/a '''
2671n/a usage_when_required = '''\
2672n/a usage: PROG [-h] (--bar BAR | --baz BAZ)
2673n/a '''
2674n/a help = '''\
2675n/a
2676n/a optional arguments:
2677n/a -h, --help show this help message and exit
2678n/a
2679n/a Titled group:
2680n/a Group description
2681n/a
2682n/a --bar BAR bar help
2683n/a --baz BAZ baz help
2684n/a '''
2685n/a
2686n/a
2687n/aclass TestMutuallyExclusiveOptionalsAndPositionalsMixed(MEMixin, TestCase):
2688n/a
2689n/a def get_parser(self, required):
2690n/a parser = ErrorRaisingArgumentParser(prog='PROG')
2691n/a parser.add_argument('x', help='x help')
2692n/a parser.add_argument('-y', action='store_true', help='y help')
2693n/a group = parser.add_mutually_exclusive_group(required=required)
2694n/a group.add_argument('a', nargs='?', help='a help')
2695n/a group.add_argument('-b', action='store_true', help='b help')
2696n/a group.add_argument('-c', action='store_true', help='c help')
2697n/a return parser
2698n/a
2699n/a failures = ['X A -b', '-b -c', '-c X A']
2700n/a successes = [
2701n/a ('X A', NS(a='A', b=False, c=False, x='X', y=False)),
2702n/a ('X -b', NS(a=None, b=True, c=False, x='X', y=False)),
2703n/a ('X -c', NS(a=None, b=False, c=True, x='X', y=False)),
2704n/a ('X A -y', NS(a='A', b=False, c=False, x='X', y=True)),
2705n/a ('X -y -b', NS(a=None, b=True, c=False, x='X', y=True)),
2706n/a ]
2707n/a successes_when_not_required = [
2708n/a ('X', NS(a=None, b=False, c=False, x='X', y=False)),
2709n/a ('X -y', NS(a=None, b=False, c=False, x='X', y=True)),
2710n/a ]
2711n/a
2712n/a usage_when_required = usage_when_not_required = '''\
2713n/a usage: PROG [-h] [-y] [-b] [-c] x [a]
2714n/a '''
2715n/a help = '''\
2716n/a
2717n/a positional arguments:
2718n/a x x help
2719n/a a a help
2720n/a
2721n/a optional arguments:
2722n/a -h, --help show this help message and exit
2723n/a -y y help
2724n/a -b b help
2725n/a -c c help
2726n/a '''
2727n/a
2728n/a# =================================================
2729n/a# Mutually exclusive group in parent parser tests
2730n/a# =================================================
2731n/a
2732n/aclass MEPBase(object):
2733n/a
2734n/a def get_parser(self, required=None):
2735n/a parent = super(MEPBase, self).get_parser(required=required)
2736n/a parser = ErrorRaisingArgumentParser(
2737n/a prog=parent.prog, add_help=False, parents=[parent])
2738n/a return parser
2739n/a
2740n/a
2741n/aclass TestMutuallyExclusiveGroupErrorsParent(
2742n/a MEPBase, TestMutuallyExclusiveGroupErrors):
2743n/a pass
2744n/a
2745n/a
2746n/aclass TestMutuallyExclusiveSimpleParent(
2747n/a MEPBase, TestMutuallyExclusiveSimple):
2748n/a pass
2749n/a
2750n/a
2751n/aclass TestMutuallyExclusiveLongParent(
2752n/a MEPBase, TestMutuallyExclusiveLong):
2753n/a pass
2754n/a
2755n/a
2756n/aclass TestMutuallyExclusiveFirstSuppressedParent(
2757n/a MEPBase, TestMutuallyExclusiveFirstSuppressed):
2758n/a pass
2759n/a
2760n/a
2761n/aclass TestMutuallyExclusiveManySuppressedParent(
2762n/a MEPBase, TestMutuallyExclusiveManySuppressed):
2763n/a pass
2764n/a
2765n/a
2766n/aclass TestMutuallyExclusiveOptionalAndPositionalParent(
2767n/a MEPBase, TestMutuallyExclusiveOptionalAndPositional):
2768n/a pass
2769n/a
2770n/a
2771n/aclass TestMutuallyExclusiveOptionalsMixedParent(
2772n/a MEPBase, TestMutuallyExclusiveOptionalsMixed):
2773n/a pass
2774n/a
2775n/a
2776n/aclass TestMutuallyExclusiveOptionalsAndPositionalsMixedParent(
2777n/a MEPBase, TestMutuallyExclusiveOptionalsAndPositionalsMixed):
2778n/a pass
2779n/a
2780n/a# =================
2781n/a# Set default tests
2782n/a# =================
2783n/a
2784n/aclass TestSetDefaults(TestCase):
2785n/a
2786n/a def test_set_defaults_no_args(self):
2787n/a parser = ErrorRaisingArgumentParser()
2788n/a parser.set_defaults(x='foo')
2789n/a parser.set_defaults(y='bar', z=1)
2790n/a self.assertEqual(NS(x='foo', y='bar', z=1),
2791n/a parser.parse_args([]))
2792n/a self.assertEqual(NS(x='foo', y='bar', z=1),
2793n/a parser.parse_args([], NS()))
2794n/a self.assertEqual(NS(x='baz', y='bar', z=1),
2795n/a parser.parse_args([], NS(x='baz')))
2796n/a self.assertEqual(NS(x='baz', y='bar', z=2),
2797n/a parser.parse_args([], NS(x='baz', z=2)))
2798n/a
2799n/a def test_set_defaults_with_args(self):
2800n/a parser = ErrorRaisingArgumentParser()
2801n/a parser.set_defaults(x='foo', y='bar')
2802n/a parser.add_argument('-x', default='xfoox')
2803n/a self.assertEqual(NS(x='xfoox', y='bar'),
2804n/a parser.parse_args([]))
2805n/a self.assertEqual(NS(x='xfoox', y='bar'),
2806n/a parser.parse_args([], NS()))
2807n/a self.assertEqual(NS(x='baz', y='bar'),
2808n/a parser.parse_args([], NS(x='baz')))
2809n/a self.assertEqual(NS(x='1', y='bar'),
2810n/a parser.parse_args('-x 1'.split()))
2811n/a self.assertEqual(NS(x='1', y='bar'),
2812n/a parser.parse_args('-x 1'.split(), NS()))
2813n/a self.assertEqual(NS(x='1', y='bar'),
2814n/a parser.parse_args('-x 1'.split(), NS(x='baz')))
2815n/a
2816n/a def test_set_defaults_subparsers(self):
2817n/a parser = ErrorRaisingArgumentParser()
2818n/a parser.set_defaults(x='foo')
2819n/a subparsers = parser.add_subparsers()
2820n/a parser_a = subparsers.add_parser('a')
2821n/a parser_a.set_defaults(y='bar')
2822n/a self.assertEqual(NS(x='foo', y='bar'),
2823n/a parser.parse_args('a'.split()))
2824n/a
2825n/a def test_set_defaults_parents(self):
2826n/a parent = ErrorRaisingArgumentParser(add_help=False)
2827n/a parent.set_defaults(x='foo')
2828n/a parser = ErrorRaisingArgumentParser(parents=[parent])
2829n/a self.assertEqual(NS(x='foo'), parser.parse_args([]))
2830n/a
2831n/a def test_set_defaults_on_parent_and_subparser(self):
2832n/a parser = argparse.ArgumentParser()
2833n/a xparser = parser.add_subparsers().add_parser('X')
2834n/a parser.set_defaults(foo=1)
2835n/a xparser.set_defaults(foo=2)
2836n/a self.assertEqual(NS(foo=2), parser.parse_args(['X']))
2837n/a
2838n/a def test_set_defaults_same_as_add_argument(self):
2839n/a parser = ErrorRaisingArgumentParser()
2840n/a parser.set_defaults(w='W', x='X', y='Y', z='Z')
2841n/a parser.add_argument('-w')
2842n/a parser.add_argument('-x', default='XX')
2843n/a parser.add_argument('y', nargs='?')
2844n/a parser.add_argument('z', nargs='?', default='ZZ')
2845n/a
2846n/a # defaults set previously
2847n/a self.assertEqual(NS(w='W', x='XX', y='Y', z='ZZ'),
2848n/a parser.parse_args([]))
2849n/a
2850n/a # reset defaults
2851n/a parser.set_defaults(w='WW', x='X', y='YY', z='Z')
2852n/a self.assertEqual(NS(w='WW', x='X', y='YY', z='Z'),
2853n/a parser.parse_args([]))
2854n/a
2855n/a def test_set_defaults_same_as_add_argument_group(self):
2856n/a parser = ErrorRaisingArgumentParser()
2857n/a parser.set_defaults(w='W', x='X', y='Y', z='Z')
2858n/a group = parser.add_argument_group('foo')
2859n/a group.add_argument('-w')
2860n/a group.add_argument('-x', default='XX')
2861n/a group.add_argument('y', nargs='?')
2862n/a group.add_argument('z', nargs='?', default='ZZ')
2863n/a
2864n/a
2865n/a # defaults set previously
2866n/a self.assertEqual(NS(w='W', x='XX', y='Y', z='ZZ'),
2867n/a parser.parse_args([]))
2868n/a
2869n/a # reset defaults
2870n/a parser.set_defaults(w='WW', x='X', y='YY', z='Z')
2871n/a self.assertEqual(NS(w='WW', x='X', y='YY', z='Z'),
2872n/a parser.parse_args([]))
2873n/a
2874n/a# =================
2875n/a# Get default tests
2876n/a# =================
2877n/a
2878n/aclass TestGetDefault(TestCase):
2879n/a
2880n/a def test_get_default(self):
2881n/a parser = ErrorRaisingArgumentParser()
2882n/a self.assertIsNone(parser.get_default("foo"))
2883n/a self.assertIsNone(parser.get_default("bar"))
2884n/a
2885n/a parser.add_argument("--foo")
2886n/a self.assertIsNone(parser.get_default("foo"))
2887n/a self.assertIsNone(parser.get_default("bar"))
2888n/a
2889n/a parser.add_argument("--bar", type=int, default=42)
2890n/a self.assertIsNone(parser.get_default("foo"))
2891n/a self.assertEqual(42, parser.get_default("bar"))
2892n/a
2893n/a parser.set_defaults(foo="badger")
2894n/a self.assertEqual("badger", parser.get_default("foo"))
2895n/a self.assertEqual(42, parser.get_default("bar"))
2896n/a
2897n/a# ==========================
2898n/a# Namespace 'contains' tests
2899n/a# ==========================
2900n/a
2901n/aclass TestNamespaceContainsSimple(TestCase):
2902n/a
2903n/a def test_empty(self):
2904n/a ns = argparse.Namespace()
2905n/a self.assertNotIn('', ns)
2906n/a self.assertNotIn('x', ns)
2907n/a
2908n/a def test_non_empty(self):
2909n/a ns = argparse.Namespace(x=1, y=2)
2910n/a self.assertNotIn('', ns)
2911n/a self.assertIn('x', ns)
2912n/a self.assertIn('y', ns)
2913n/a self.assertNotIn('xx', ns)
2914n/a self.assertNotIn('z', ns)
2915n/a
2916n/a# =====================
2917n/a# Help formatting tests
2918n/a# =====================
2919n/a
2920n/aclass TestHelpFormattingMetaclass(type):
2921n/a
2922n/a def __init__(cls, name, bases, bodydict):
2923n/a if name == 'HelpTestCase':
2924n/a return
2925n/a
2926n/a class AddTests(object):
2927n/a
2928n/a def __init__(self, test_class, func_suffix, std_name):
2929n/a self.func_suffix = func_suffix
2930n/a self.std_name = std_name
2931n/a
2932n/a for test_func in [self.test_format,
2933n/a self.test_print,
2934n/a self.test_print_file]:
2935n/a test_name = '%s_%s' % (test_func.__name__, func_suffix)
2936n/a
2937n/a def test_wrapper(self, test_func=test_func):
2938n/a test_func(self)
2939n/a try:
2940n/a test_wrapper.__name__ = test_name
2941n/a except TypeError:
2942n/a pass
2943n/a setattr(test_class, test_name, test_wrapper)
2944n/a
2945n/a def _get_parser(self, tester):
2946n/a parser = argparse.ArgumentParser(
2947n/a *tester.parser_signature.args,
2948n/a **tester.parser_signature.kwargs)
2949n/a for argument_sig in getattr(tester, 'argument_signatures', []):
2950n/a parser.add_argument(*argument_sig.args,
2951n/a **argument_sig.kwargs)
2952n/a group_sigs = getattr(tester, 'argument_group_signatures', [])
2953n/a for group_sig, argument_sigs in group_sigs:
2954n/a group = parser.add_argument_group(*group_sig.args,
2955n/a **group_sig.kwargs)
2956n/a for argument_sig in argument_sigs:
2957n/a group.add_argument(*argument_sig.args,
2958n/a **argument_sig.kwargs)
2959n/a subparsers_sigs = getattr(tester, 'subparsers_signatures', [])
2960n/a if subparsers_sigs:
2961n/a subparsers = parser.add_subparsers()
2962n/a for subparser_sig in subparsers_sigs:
2963n/a subparsers.add_parser(*subparser_sig.args,
2964n/a **subparser_sig.kwargs)
2965n/a return parser
2966n/a
2967n/a def _test(self, tester, parser_text):
2968n/a expected_text = getattr(tester, self.func_suffix)
2969n/a expected_text = textwrap.dedent(expected_text)
2970n/a tester.assertEqual(expected_text, parser_text)
2971n/a
2972n/a def test_format(self, tester):
2973n/a parser = self._get_parser(tester)
2974n/a format = getattr(parser, 'format_%s' % self.func_suffix)
2975n/a self._test(tester, format())
2976n/a
2977n/a def test_print(self, tester):
2978n/a parser = self._get_parser(tester)
2979n/a print_ = getattr(parser, 'print_%s' % self.func_suffix)
2980n/a old_stream = getattr(sys, self.std_name)
2981n/a setattr(sys, self.std_name, StdIOBuffer())
2982n/a try:
2983n/a print_()
2984n/a parser_text = getattr(sys, self.std_name).getvalue()
2985n/a finally:
2986n/a setattr(sys, self.std_name, old_stream)
2987n/a self._test(tester, parser_text)
2988n/a
2989n/a def test_print_file(self, tester):
2990n/a parser = self._get_parser(tester)
2991n/a print_ = getattr(parser, 'print_%s' % self.func_suffix)
2992n/a sfile = StdIOBuffer()
2993n/a print_(sfile)
2994n/a parser_text = sfile.getvalue()
2995n/a self._test(tester, parser_text)
2996n/a
2997n/a # add tests for {format,print}_{usage,help}
2998n/a for func_suffix, std_name in [('usage', 'stdout'),
2999n/a ('help', 'stdout')]:
3000n/a AddTests(cls, func_suffix, std_name)
3001n/a
3002n/abases = TestCase,
3003n/aHelpTestCase = TestHelpFormattingMetaclass('HelpTestCase', bases, {})
3004n/a
3005n/a
3006n/aclass TestHelpBiggerOptionals(HelpTestCase):
3007n/a """Make sure that argument help aligns when options are longer"""
3008n/a
3009n/a parser_signature = Sig(prog='PROG', description='DESCRIPTION',
3010n/a epilog='EPILOG')
3011n/a argument_signatures = [
3012n/a Sig('-v', '--version', action='version', version='0.1'),
3013n/a Sig('-x', action='store_true', help='X HELP'),
3014n/a Sig('--y', help='Y HELP'),
3015n/a Sig('foo', help='FOO HELP'),
3016n/a Sig('bar', help='BAR HELP'),
3017n/a ]
3018n/a argument_group_signatures = []
3019n/a usage = '''\
3020n/a usage: PROG [-h] [-v] [-x] [--y Y] foo bar
3021n/a '''
3022n/a help = usage + '''\
3023n/a
3024n/a DESCRIPTION
3025n/a
3026n/a positional arguments:
3027n/a foo FOO HELP
3028n/a bar BAR HELP
3029n/a
3030n/a optional arguments:
3031n/a -h, --help show this help message and exit
3032n/a -v, --version show program's version number and exit
3033n/a -x X HELP
3034n/a --y Y Y HELP
3035n/a
3036n/a EPILOG
3037n/a '''
3038n/a version = '''\
3039n/a 0.1
3040n/a '''
3041n/a
3042n/aclass TestShortColumns(HelpTestCase):
3043n/a '''Test extremely small number of columns.
3044n/a
3045n/a TestCase prevents "COLUMNS" from being too small in the tests themselves,
3046n/a but we don't want any exceptions thrown in such cases. Only ugly representation.
3047n/a '''
3048n/a def setUp(self):
3049n/a env = support.EnvironmentVarGuard()
3050n/a env.set("COLUMNS", '15')
3051n/a self.addCleanup(env.__exit__)
3052n/a
3053n/a parser_signature = TestHelpBiggerOptionals.parser_signature
3054n/a argument_signatures = TestHelpBiggerOptionals.argument_signatures
3055n/a argument_group_signatures = TestHelpBiggerOptionals.argument_group_signatures
3056n/a usage = '''\
3057n/a usage: PROG
3058n/a [-h]
3059n/a [-v]
3060n/a [-x]
3061n/a [--y Y]
3062n/a foo
3063n/a bar
3064n/a '''
3065n/a help = usage + '''\
3066n/a
3067n/a DESCRIPTION
3068n/a
3069n/a positional arguments:
3070n/a foo
3071n/a FOO HELP
3072n/a bar
3073n/a BAR HELP
3074n/a
3075n/a optional arguments:
3076n/a -h, --help
3077n/a show this
3078n/a help
3079n/a message and
3080n/a exit
3081n/a -v, --version
3082n/a show
3083n/a program's
3084n/a version
3085n/a number and
3086n/a exit
3087n/a -x
3088n/a X HELP
3089n/a --y Y
3090n/a Y HELP
3091n/a
3092n/a EPILOG
3093n/a '''
3094n/a version = TestHelpBiggerOptionals.version
3095n/a
3096n/a
3097n/aclass TestHelpBiggerOptionalGroups(HelpTestCase):
3098n/a """Make sure that argument help aligns when options are longer"""
3099n/a
3100n/a parser_signature = Sig(prog='PROG', description='DESCRIPTION',
3101n/a epilog='EPILOG')
3102n/a argument_signatures = [
3103n/a Sig('-v', '--version', action='version', version='0.1'),
3104n/a Sig('-x', action='store_true', help='X HELP'),
3105n/a Sig('--y', help='Y HELP'),
3106n/a Sig('foo', help='FOO HELP'),
3107n/a Sig('bar', help='BAR HELP'),
3108n/a ]
3109n/a argument_group_signatures = [
3110n/a (Sig('GROUP TITLE', description='GROUP DESCRIPTION'), [
3111n/a Sig('baz', help='BAZ HELP'),
3112n/a Sig('-z', nargs='+', help='Z HELP')]),
3113n/a ]
3114n/a usage = '''\
3115n/a usage: PROG [-h] [-v] [-x] [--y Y] [-z Z [Z ...]] foo bar baz
3116n/a '''
3117n/a help = usage + '''\
3118n/a
3119n/a DESCRIPTION
3120n/a
3121n/a positional arguments:
3122n/a foo FOO HELP
3123n/a bar BAR HELP
3124n/a
3125n/a optional arguments:
3126n/a -h, --help show this help message and exit
3127n/a -v, --version show program's version number and exit
3128n/a -x X HELP
3129n/a --y Y Y HELP
3130n/a
3131n/a GROUP TITLE:
3132n/a GROUP DESCRIPTION
3133n/a
3134n/a baz BAZ HELP
3135n/a -z Z [Z ...] Z HELP
3136n/a
3137n/a EPILOG
3138n/a '''
3139n/a version = '''\
3140n/a 0.1
3141n/a '''
3142n/a
3143n/a
3144n/aclass TestHelpBiggerPositionals(HelpTestCase):
3145n/a """Make sure that help aligns when arguments are longer"""
3146n/a
3147n/a parser_signature = Sig(usage='USAGE', description='DESCRIPTION')
3148n/a argument_signatures = [
3149n/a Sig('-x', action='store_true', help='X HELP'),
3150n/a Sig('--y', help='Y HELP'),
3151n/a Sig('ekiekiekifekang', help='EKI HELP'),
3152n/a Sig('bar', help='BAR HELP'),
3153n/a ]
3154n/a argument_group_signatures = []
3155n/a usage = '''\
3156n/a usage: USAGE
3157n/a '''
3158n/a help = usage + '''\
3159n/a
3160n/a DESCRIPTION
3161n/a
3162n/a positional arguments:
3163n/a ekiekiekifekang EKI HELP
3164n/a bar BAR HELP
3165n/a
3166n/a optional arguments:
3167n/a -h, --help show this help message and exit
3168n/a -x X HELP
3169n/a --y Y Y HELP
3170n/a '''
3171n/a
3172n/a version = ''
3173n/a
3174n/a
3175n/aclass TestHelpReformatting(HelpTestCase):
3176n/a """Make sure that text after short names starts on the first line"""
3177n/a
3178n/a parser_signature = Sig(
3179n/a prog='PROG',
3180n/a description=' oddly formatted\n'
3181n/a 'description\n'
3182n/a '\n'
3183n/a 'that is so long that it should go onto multiple '
3184n/a 'lines when wrapped')
3185n/a argument_signatures = [
3186n/a Sig('-x', metavar='XX', help='oddly\n'
3187n/a ' formatted -x help'),
3188n/a Sig('y', metavar='yyy', help='normal y help'),
3189n/a ]
3190n/a argument_group_signatures = [
3191n/a (Sig('title', description='\n'
3192n/a ' oddly formatted group\n'
3193n/a '\n'
3194n/a 'description'),
3195n/a [Sig('-a', action='store_true',
3196n/a help=' oddly \n'
3197n/a 'formatted -a help \n'
3198n/a ' again, so long that it should be wrapped over '
3199n/a 'multiple lines')]),
3200n/a ]
3201n/a usage = '''\
3202n/a usage: PROG [-h] [-x XX] [-a] yyy
3203n/a '''
3204n/a help = usage + '''\
3205n/a
3206n/a oddly formatted description that is so long that it should go onto \
3207n/amultiple
3208n/a lines when wrapped
3209n/a
3210n/a positional arguments:
3211n/a yyy normal y help
3212n/a
3213n/a optional arguments:
3214n/a -h, --help show this help message and exit
3215n/a -x XX oddly formatted -x help
3216n/a
3217n/a title:
3218n/a oddly formatted group description
3219n/a
3220n/a -a oddly formatted -a help again, so long that it should \
3221n/abe wrapped
3222n/a over multiple lines
3223n/a '''
3224n/a version = ''
3225n/a
3226n/a
3227n/aclass TestHelpWrappingShortNames(HelpTestCase):
3228n/a """Make sure that text after short names starts on the first line"""
3229n/a
3230n/a parser_signature = Sig(prog='PROG', description= 'D\nD' * 30)
3231n/a argument_signatures = [
3232n/a Sig('-x', metavar='XX', help='XHH HX' * 20),
3233n/a Sig('y', metavar='yyy', help='YH YH' * 20),
3234n/a ]
3235n/a argument_group_signatures = [
3236n/a (Sig('ALPHAS'), [
3237n/a Sig('-a', action='store_true', help='AHHH HHA' * 10)]),
3238n/a ]
3239n/a usage = '''\
3240n/a usage: PROG [-h] [-x XX] [-a] yyy
3241n/a '''
3242n/a help = usage + '''\
3243n/a
3244n/a D DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD \
3245n/aDD DD DD
3246n/a DD DD DD DD D
3247n/a
3248n/a positional arguments:
3249n/a yyy YH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH \
3250n/aYHYH YHYH
3251n/a YHYH YHYH YHYH YHYH YHYH YHYH YHYH YH
3252n/a
3253n/a optional arguments:
3254n/a -h, --help show this help message and exit
3255n/a -x XX XHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH \
3256n/aHXXHH HXXHH
3257n/a HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HX
3258n/a
3259n/a ALPHAS:
3260n/a -a AHHH HHAAHHH HHAAHHH HHAAHHH HHAAHHH HHAAHHH HHAAHHH \
3261n/aHHAAHHH
3262n/a HHAAHHH HHAAHHH HHA
3263n/a '''
3264n/a version = ''
3265n/a
3266n/a
3267n/aclass TestHelpWrappingLongNames(HelpTestCase):
3268n/a """Make sure that text after long names starts on the next line"""
3269n/a
3270n/a parser_signature = Sig(usage='USAGE', description= 'D D' * 30)
3271n/a argument_signatures = [
3272n/a Sig('-v', '--version', action='version', version='V V' * 30),
3273n/a Sig('-x', metavar='X' * 25, help='XH XH' * 20),
3274n/a Sig('y', metavar='y' * 25, help='YH YH' * 20),
3275n/a ]
3276n/a argument_group_signatures = [
3277n/a (Sig('ALPHAS'), [
3278n/a Sig('-a', metavar='A' * 25, help='AH AH' * 20),
3279n/a Sig('z', metavar='z' * 25, help='ZH ZH' * 20)]),
3280n/a ]
3281n/a usage = '''\
3282n/a usage: USAGE
3283n/a '''
3284n/a help = usage + '''\
3285n/a
3286n/a D DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD \
3287n/aDD DD DD
3288n/a DD DD DD DD D
3289n/a
3290n/a positional arguments:
3291n/a yyyyyyyyyyyyyyyyyyyyyyyyy
3292n/a YH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH \
3293n/aYHYH YHYH
3294n/a YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YH
3295n/a
3296n/a optional arguments:
3297n/a -h, --help show this help message and exit
3298n/a -v, --version show program's version number and exit
3299n/a -x XXXXXXXXXXXXXXXXXXXXXXXXX
3300n/a XH XHXH XHXH XHXH XHXH XHXH XHXH XHXH XHXH \
3301n/aXHXH XHXH
3302n/a XHXH XHXH XHXH XHXH XHXH XHXH XHXH XHXH XHXH XH
3303n/a
3304n/a ALPHAS:
3305n/a -a AAAAAAAAAAAAAAAAAAAAAAAAA
3306n/a AH AHAH AHAH AHAH AHAH AHAH AHAH AHAH AHAH \
3307n/aAHAH AHAH
3308n/a AHAH AHAH AHAH AHAH AHAH AHAH AHAH AHAH AHAH AH
3309n/a zzzzzzzzzzzzzzzzzzzzzzzzz
3310n/a ZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH \
3311n/aZHZH ZHZH
3312n/a ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZH
3313n/a '''
3314n/a version = '''\
3315n/a V VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV \
3316n/aVV VV VV
3317n/a VV VV VV VV V
3318n/a '''
3319n/a
3320n/a
3321n/aclass TestHelpUsage(HelpTestCase):
3322n/a """Test basic usage messages"""
3323n/a
3324n/a parser_signature = Sig(prog='PROG')
3325n/a argument_signatures = [
3326n/a Sig('-w', nargs='+', help='w'),
3327n/a Sig('-x', nargs='*', help='x'),
3328n/a Sig('a', help='a'),
3329n/a Sig('b', help='b', nargs=2),
3330n/a Sig('c', help='c', nargs='?'),
3331n/a ]
3332n/a argument_group_signatures = [
3333n/a (Sig('group'), [
3334n/a Sig('-y', nargs='?', help='y'),
3335n/a Sig('-z', nargs=3, help='z'),
3336n/a Sig('d', help='d', nargs='*'),
3337n/a Sig('e', help='e', nargs='+'),
3338n/a ])
3339n/a ]
3340n/a usage = '''\
3341n/a usage: PROG [-h] [-w W [W ...]] [-x [X [X ...]]] [-y [Y]] [-z Z Z Z]
3342n/a a b b [c] [d [d ...]] e [e ...]
3343n/a '''
3344n/a help = usage + '''\
3345n/a
3346n/a positional arguments:
3347n/a a a
3348n/a b b
3349n/a c c
3350n/a
3351n/a optional arguments:
3352n/a -h, --help show this help message and exit
3353n/a -w W [W ...] w
3354n/a -x [X [X ...]] x
3355n/a
3356n/a group:
3357n/a -y [Y] y
3358n/a -z Z Z Z z
3359n/a d d
3360n/a e e
3361n/a '''
3362n/a version = ''
3363n/a
3364n/a
3365n/aclass TestHelpOnlyUserGroups(HelpTestCase):
3366n/a """Test basic usage messages"""
3367n/a
3368n/a parser_signature = Sig(prog='PROG', add_help=False)
3369n/a argument_signatures = []
3370n/a argument_group_signatures = [
3371n/a (Sig('xxxx'), [
3372n/a Sig('-x', help='x'),
3373n/a Sig('a', help='a'),
3374n/a ]),
3375n/a (Sig('yyyy'), [
3376n/a Sig('b', help='b'),
3377n/a Sig('-y', help='y'),
3378n/a ]),
3379n/a ]
3380n/a usage = '''\
3381n/a usage: PROG [-x X] [-y Y] a b
3382n/a '''
3383n/a help = usage + '''\
3384n/a
3385n/a xxxx:
3386n/a -x X x
3387n/a a a
3388n/a
3389n/a yyyy:
3390n/a b b
3391n/a -y Y y
3392n/a '''
3393n/a version = ''
3394n/a
3395n/a
3396n/aclass TestHelpUsageLongProg(HelpTestCase):
3397n/a """Test usage messages where the prog is long"""
3398n/a
3399n/a parser_signature = Sig(prog='P' * 60)
3400n/a argument_signatures = [
3401n/a Sig('-w', metavar='W'),
3402n/a Sig('-x', metavar='X'),
3403n/a Sig('a'),
3404n/a Sig('b'),
3405n/a ]
3406n/a argument_group_signatures = []
3407n/a usage = '''\
3408n/a usage: PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
3409n/a [-h] [-w W] [-x X] a b
3410n/a '''
3411n/a help = usage + '''\
3412n/a
3413n/a positional arguments:
3414n/a a
3415n/a b
3416n/a
3417n/a optional arguments:
3418n/a -h, --help show this help message and exit
3419n/a -w W
3420n/a -x X
3421n/a '''
3422n/a version = ''
3423n/a
3424n/a
3425n/aclass TestHelpUsageLongProgOptionsWrap(HelpTestCase):
3426n/a """Test usage messages where the prog is long and the optionals wrap"""
3427n/a
3428n/a parser_signature = Sig(prog='P' * 60)
3429n/a argument_signatures = [
3430n/a Sig('-w', metavar='W' * 25),
3431n/a Sig('-x', metavar='X' * 25),
3432n/a Sig('-y', metavar='Y' * 25),
3433n/a Sig('-z', metavar='Z' * 25),
3434n/a Sig('a'),
3435n/a Sig('b'),
3436n/a ]
3437n/a argument_group_signatures = []
3438n/a usage = '''\
3439n/a usage: PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
3440n/a [-h] [-w WWWWWWWWWWWWWWWWWWWWWWWWW] \
3441n/a[-x XXXXXXXXXXXXXXXXXXXXXXXXX]
3442n/a [-y YYYYYYYYYYYYYYYYYYYYYYYYY] [-z ZZZZZZZZZZZZZZZZZZZZZZZZZ]
3443n/a a b
3444n/a '''
3445n/a help = usage + '''\
3446n/a
3447n/a positional arguments:
3448n/a a
3449n/a b
3450n/a
3451n/a optional arguments:
3452n/a -h, --help show this help message and exit
3453n/a -w WWWWWWWWWWWWWWWWWWWWWWWWW
3454n/a -x XXXXXXXXXXXXXXXXXXXXXXXXX
3455n/a -y YYYYYYYYYYYYYYYYYYYYYYYYY
3456n/a -z ZZZZZZZZZZZZZZZZZZZZZZZZZ
3457n/a '''
3458n/a version = ''
3459n/a
3460n/a
3461n/aclass TestHelpUsageLongProgPositionalsWrap(HelpTestCase):
3462n/a """Test usage messages where the prog is long and the positionals wrap"""
3463n/a
3464n/a parser_signature = Sig(prog='P' * 60, add_help=False)
3465n/a argument_signatures = [
3466n/a Sig('a' * 25),
3467n/a Sig('b' * 25),
3468n/a Sig('c' * 25),
3469n/a ]
3470n/a argument_group_signatures = []
3471n/a usage = '''\
3472n/a usage: PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
3473n/a aaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbb
3474n/a ccccccccccccccccccccccccc
3475n/a '''
3476n/a help = usage + '''\
3477n/a
3478n/a positional arguments:
3479n/a aaaaaaaaaaaaaaaaaaaaaaaaa
3480n/a bbbbbbbbbbbbbbbbbbbbbbbbb
3481n/a ccccccccccccccccccccccccc
3482n/a '''
3483n/a version = ''
3484n/a
3485n/a
3486n/aclass TestHelpUsageOptionalsWrap(HelpTestCase):
3487n/a """Test usage messages where the optionals wrap"""
3488n/a
3489n/a parser_signature = Sig(prog='PROG')
3490n/a argument_signatures = [
3491n/a Sig('-w', metavar='W' * 25),
3492n/a Sig('-x', metavar='X' * 25),
3493n/a Sig('-y', metavar='Y' * 25),
3494n/a Sig('-z', metavar='Z' * 25),
3495n/a Sig('a'),
3496n/a Sig('b'),
3497n/a Sig('c'),
3498n/a ]
3499n/a argument_group_signatures = []
3500n/a usage = '''\
3501n/a usage: PROG [-h] [-w WWWWWWWWWWWWWWWWWWWWWWWWW] \
3502n/a[-x XXXXXXXXXXXXXXXXXXXXXXXXX]
3503n/a [-y YYYYYYYYYYYYYYYYYYYYYYYYY] \
3504n/a[-z ZZZZZZZZZZZZZZZZZZZZZZZZZ]
3505n/a a b c
3506n/a '''
3507n/a help = usage + '''\
3508n/a
3509n/a positional arguments:
3510n/a a
3511n/a b
3512n/a c
3513n/a
3514n/a optional arguments:
3515n/a -h, --help show this help message and exit
3516n/a -w WWWWWWWWWWWWWWWWWWWWWWWWW
3517n/a -x XXXXXXXXXXXXXXXXXXXXXXXXX
3518n/a -y YYYYYYYYYYYYYYYYYYYYYYYYY
3519n/a -z ZZZZZZZZZZZZZZZZZZZZZZZZZ
3520n/a '''
3521n/a version = ''
3522n/a
3523n/a
3524n/aclass TestHelpUsagePositionalsWrap(HelpTestCase):
3525n/a """Test usage messages where the positionals wrap"""
3526n/a
3527n/a parser_signature = Sig(prog='PROG')
3528n/a argument_signatures = [
3529n/a Sig('-x'),
3530n/a Sig('-y'),
3531n/a Sig('-z'),
3532n/a Sig('a' * 25),
3533n/a Sig('b' * 25),
3534n/a Sig('c' * 25),
3535n/a ]
3536n/a argument_group_signatures = []
3537n/a usage = '''\
3538n/a usage: PROG [-h] [-x X] [-y Y] [-z Z]
3539n/a aaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbb
3540n/a ccccccccccccccccccccccccc
3541n/a '''
3542n/a help = usage + '''\
3543n/a
3544n/a positional arguments:
3545n/a aaaaaaaaaaaaaaaaaaaaaaaaa
3546n/a bbbbbbbbbbbbbbbbbbbbbbbbb
3547n/a ccccccccccccccccccccccccc
3548n/a
3549n/a optional arguments:
3550n/a -h, --help show this help message and exit
3551n/a -x X
3552n/a -y Y
3553n/a -z Z
3554n/a '''
3555n/a version = ''
3556n/a
3557n/a
3558n/aclass TestHelpUsageOptionalsPositionalsWrap(HelpTestCase):
3559n/a """Test usage messages where the optionals and positionals wrap"""
3560n/a
3561n/a parser_signature = Sig(prog='PROG')
3562n/a argument_signatures = [
3563n/a Sig('-x', metavar='X' * 25),
3564n/a Sig('-y', metavar='Y' * 25),
3565n/a Sig('-z', metavar='Z' * 25),
3566n/a Sig('a' * 25),
3567n/a Sig('b' * 25),
3568n/a Sig('c' * 25),
3569n/a ]
3570n/a argument_group_signatures = []
3571n/a usage = '''\
3572n/a usage: PROG [-h] [-x XXXXXXXXXXXXXXXXXXXXXXXXX] \
3573n/a[-y YYYYYYYYYYYYYYYYYYYYYYYYY]
3574n/a [-z ZZZZZZZZZZZZZZZZZZZZZZZZZ]
3575n/a aaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbb
3576n/a ccccccccccccccccccccccccc
3577n/a '''
3578n/a help = usage + '''\
3579n/a
3580n/a positional arguments:
3581n/a aaaaaaaaaaaaaaaaaaaaaaaaa
3582n/a bbbbbbbbbbbbbbbbbbbbbbbbb
3583n/a ccccccccccccccccccccccccc
3584n/a
3585n/a optional arguments:
3586n/a -h, --help show this help message and exit
3587n/a -x XXXXXXXXXXXXXXXXXXXXXXXXX
3588n/a -y YYYYYYYYYYYYYYYYYYYYYYYYY
3589n/a -z ZZZZZZZZZZZZZZZZZZZZZZZZZ
3590n/a '''
3591n/a version = ''
3592n/a
3593n/a
3594n/aclass TestHelpUsageOptionalsOnlyWrap(HelpTestCase):
3595n/a """Test usage messages where there are only optionals and they wrap"""
3596n/a
3597n/a parser_signature = Sig(prog='PROG')
3598n/a argument_signatures = [
3599n/a Sig('-x', metavar='X' * 25),
3600n/a Sig('-y', metavar='Y' * 25),
3601n/a Sig('-z', metavar='Z' * 25),
3602n/a ]
3603n/a argument_group_signatures = []
3604n/a usage = '''\
3605n/a usage: PROG [-h] [-x XXXXXXXXXXXXXXXXXXXXXXXXX] \
3606n/a[-y YYYYYYYYYYYYYYYYYYYYYYYYY]
3607n/a [-z ZZZZZZZZZZZZZZZZZZZZZZZZZ]
3608n/a '''
3609n/a help = usage + '''\
3610n/a
3611n/a optional arguments:
3612n/a -h, --help show this help message and exit
3613n/a -x XXXXXXXXXXXXXXXXXXXXXXXXX
3614n/a -y YYYYYYYYYYYYYYYYYYYYYYYYY
3615n/a -z ZZZZZZZZZZZZZZZZZZZZZZZZZ
3616n/a '''
3617n/a version = ''
3618n/a
3619n/a
3620n/aclass TestHelpUsagePositionalsOnlyWrap(HelpTestCase):
3621n/a """Test usage messages where there are only positionals and they wrap"""
3622n/a
3623n/a parser_signature = Sig(prog='PROG', add_help=False)
3624n/a argument_signatures = [
3625n/a Sig('a' * 25),
3626n/a Sig('b' * 25),
3627n/a Sig('c' * 25),
3628n/a ]
3629n/a argument_group_signatures = []
3630n/a usage = '''\
3631n/a usage: PROG aaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbb
3632n/a ccccccccccccccccccccccccc
3633n/a '''
3634n/a help = usage + '''\
3635n/a
3636n/a positional arguments:
3637n/a aaaaaaaaaaaaaaaaaaaaaaaaa
3638n/a bbbbbbbbbbbbbbbbbbbbbbbbb
3639n/a ccccccccccccccccccccccccc
3640n/a '''
3641n/a version = ''
3642n/a
3643n/a
3644n/aclass TestHelpVariableExpansion(HelpTestCase):
3645n/a """Test that variables are expanded properly in help messages"""
3646n/a
3647n/a parser_signature = Sig(prog='PROG')
3648n/a argument_signatures = [
3649n/a Sig('-x', type=int,
3650n/a help='x %(prog)s %(default)s %(type)s %%'),
3651n/a Sig('-y', action='store_const', default=42, const='XXX',
3652n/a help='y %(prog)s %(default)s %(const)s'),
3653n/a Sig('--foo', choices='abc',
3654n/a help='foo %(prog)s %(default)s %(choices)s'),
3655n/a Sig('--bar', default='baz', choices=[1, 2], metavar='BBB',
3656n/a help='bar %(prog)s %(default)s %(dest)s'),
3657n/a Sig('spam', help='spam %(prog)s %(default)s'),
3658n/a Sig('badger', default=0.5, help='badger %(prog)s %(default)s'),
3659n/a ]
3660n/a argument_group_signatures = [
3661n/a (Sig('group'), [
3662n/a Sig('-a', help='a %(prog)s %(default)s'),
3663n/a Sig('-b', default=-1, help='b %(prog)s %(default)s'),
3664n/a ])
3665n/a ]
3666n/a usage = ('''\
3667n/a usage: PROG [-h] [-x X] [-y] [--foo {a,b,c}] [--bar BBB] [-a A] [-b B]
3668n/a spam badger
3669n/a ''')
3670n/a help = usage + '''\
3671n/a
3672n/a positional arguments:
3673n/a spam spam PROG None
3674n/a badger badger PROG 0.5
3675n/a
3676n/a optional arguments:
3677n/a -h, --help show this help message and exit
3678n/a -x X x PROG None int %
3679n/a -y y PROG 42 XXX
3680n/a --foo {a,b,c} foo PROG None a, b, c
3681n/a --bar BBB bar PROG baz bar
3682n/a
3683n/a group:
3684n/a -a A a PROG None
3685n/a -b B b PROG -1
3686n/a '''
3687n/a version = ''
3688n/a
3689n/a
3690n/aclass TestHelpVariableExpansionUsageSupplied(HelpTestCase):
3691n/a """Test that variables are expanded properly when usage= is present"""
3692n/a
3693n/a parser_signature = Sig(prog='PROG', usage='%(prog)s FOO')
3694n/a argument_signatures = []
3695n/a argument_group_signatures = []
3696n/a usage = ('''\
3697n/a usage: PROG FOO
3698n/a ''')
3699n/a help = usage + '''\
3700n/a
3701n/a optional arguments:
3702n/a -h, --help show this help message and exit
3703n/a '''
3704n/a version = ''
3705n/a
3706n/a
3707n/aclass TestHelpVariableExpansionNoArguments(HelpTestCase):
3708n/a """Test that variables are expanded properly with no arguments"""
3709n/a
3710n/a parser_signature = Sig(prog='PROG', add_help=False)
3711n/a argument_signatures = []
3712n/a argument_group_signatures = []
3713n/a usage = ('''\
3714n/a usage: PROG
3715n/a ''')
3716n/a help = usage
3717n/a version = ''
3718n/a
3719n/a
3720n/aclass TestHelpSuppressUsage(HelpTestCase):
3721n/a """Test that items can be suppressed in usage messages"""
3722n/a
3723n/a parser_signature = Sig(prog='PROG', usage=argparse.SUPPRESS)
3724n/a argument_signatures = [
3725n/a Sig('--foo', help='foo help'),
3726n/a Sig('spam', help='spam help'),
3727n/a ]
3728n/a argument_group_signatures = []
3729n/a help = '''\
3730n/a positional arguments:
3731n/a spam spam help
3732n/a
3733n/a optional arguments:
3734n/a -h, --help show this help message and exit
3735n/a --foo FOO foo help
3736n/a '''
3737n/a usage = ''
3738n/a version = ''
3739n/a
3740n/a
3741n/aclass TestHelpSuppressOptional(HelpTestCase):
3742n/a """Test that optional arguments can be suppressed in help messages"""
3743n/a
3744n/a parser_signature = Sig(prog='PROG', add_help=False)
3745n/a argument_signatures = [
3746n/a Sig('--foo', help=argparse.SUPPRESS),
3747n/a Sig('spam', help='spam help'),
3748n/a ]
3749n/a argument_group_signatures = []
3750n/a usage = '''\
3751n/a usage: PROG spam
3752n/a '''
3753n/a help = usage + '''\
3754n/a
3755n/a positional arguments:
3756n/a spam spam help
3757n/a '''
3758n/a version = ''
3759n/a
3760n/a
3761n/aclass TestHelpSuppressOptionalGroup(HelpTestCase):
3762n/a """Test that optional groups can be suppressed in help messages"""
3763n/a
3764n/a parser_signature = Sig(prog='PROG')
3765n/a argument_signatures = [
3766n/a Sig('--foo', help='foo help'),
3767n/a Sig('spam', help='spam help'),
3768n/a ]
3769n/a argument_group_signatures = [
3770n/a (Sig('group'), [Sig('--bar', help=argparse.SUPPRESS)]),
3771n/a ]
3772n/a usage = '''\
3773n/a usage: PROG [-h] [--foo FOO] spam
3774n/a '''
3775n/a help = usage + '''\
3776n/a
3777n/a positional arguments:
3778n/a spam spam help
3779n/a
3780n/a optional arguments:
3781n/a -h, --help show this help message and exit
3782n/a --foo FOO foo help
3783n/a '''
3784n/a version = ''
3785n/a
3786n/a
3787n/aclass TestHelpSuppressPositional(HelpTestCase):
3788n/a """Test that positional arguments can be suppressed in help messages"""
3789n/a
3790n/a parser_signature = Sig(prog='PROG')
3791n/a argument_signatures = [
3792n/a Sig('--foo', help='foo help'),
3793n/a Sig('spam', help=argparse.SUPPRESS),
3794n/a ]
3795n/a argument_group_signatures = []
3796n/a usage = '''\
3797n/a usage: PROG [-h] [--foo FOO]
3798n/a '''
3799n/a help = usage + '''\
3800n/a
3801n/a optional arguments:
3802n/a -h, --help show this help message and exit
3803n/a --foo FOO foo help
3804n/a '''
3805n/a version = ''
3806n/a
3807n/a
3808n/aclass TestHelpRequiredOptional(HelpTestCase):
3809n/a """Test that required options don't look optional"""
3810n/a
3811n/a parser_signature = Sig(prog='PROG')
3812n/a argument_signatures = [
3813n/a Sig('--foo', required=True, help='foo help'),
3814n/a ]
3815n/a argument_group_signatures = []
3816n/a usage = '''\
3817n/a usage: PROG [-h] --foo FOO
3818n/a '''
3819n/a help = usage + '''\
3820n/a
3821n/a optional arguments:
3822n/a -h, --help show this help message and exit
3823n/a --foo FOO foo help
3824n/a '''
3825n/a version = ''
3826n/a
3827n/a
3828n/aclass TestHelpAlternatePrefixChars(HelpTestCase):
3829n/a """Test that options display with different prefix characters"""
3830n/a
3831n/a parser_signature = Sig(prog='PROG', prefix_chars='^;', add_help=False)
3832n/a argument_signatures = [
3833n/a Sig('^^foo', action='store_true', help='foo help'),
3834n/a Sig(';b', ';;bar', help='bar help'),
3835n/a ]
3836n/a argument_group_signatures = []
3837n/a usage = '''\
3838n/a usage: PROG [^^foo] [;b BAR]
3839n/a '''
3840n/a help = usage + '''\
3841n/a
3842n/a optional arguments:
3843n/a ^^foo foo help
3844n/a ;b BAR, ;;bar BAR bar help
3845n/a '''
3846n/a version = ''
3847n/a
3848n/a
3849n/aclass TestHelpNoHelpOptional(HelpTestCase):
3850n/a """Test that the --help argument can be suppressed help messages"""
3851n/a
3852n/a parser_signature = Sig(prog='PROG', add_help=False)
3853n/a argument_signatures = [
3854n/a Sig('--foo', help='foo help'),
3855n/a Sig('spam', help='spam help'),
3856n/a ]
3857n/a argument_group_signatures = []
3858n/a usage = '''\
3859n/a usage: PROG [--foo FOO] spam
3860n/a '''
3861n/a help = usage + '''\
3862n/a
3863n/a positional arguments:
3864n/a spam spam help
3865n/a
3866n/a optional arguments:
3867n/a --foo FOO foo help
3868n/a '''
3869n/a version = ''
3870n/a
3871n/a
3872n/aclass TestHelpNone(HelpTestCase):
3873n/a """Test that no errors occur if no help is specified"""
3874n/a
3875n/a parser_signature = Sig(prog='PROG')
3876n/a argument_signatures = [
3877n/a Sig('--foo'),
3878n/a Sig('spam'),
3879n/a ]
3880n/a argument_group_signatures = []
3881n/a usage = '''\
3882n/a usage: PROG [-h] [--foo FOO] spam
3883n/a '''
3884n/a help = usage + '''\
3885n/a
3886n/a positional arguments:
3887n/a spam
3888n/a
3889n/a optional arguments:
3890n/a -h, --help show this help message and exit
3891n/a --foo FOO
3892n/a '''
3893n/a version = ''
3894n/a
3895n/a
3896n/aclass TestHelpTupleMetavar(HelpTestCase):
3897n/a """Test specifying metavar as a tuple"""
3898n/a
3899n/a parser_signature = Sig(prog='PROG')
3900n/a argument_signatures = [
3901n/a Sig('-w', help='w', nargs='+', metavar=('W1', 'W2')),
3902n/a Sig('-x', help='x', nargs='*', metavar=('X1', 'X2')),
3903n/a Sig('-y', help='y', nargs=3, metavar=('Y1', 'Y2', 'Y3')),
3904n/a Sig('-z', help='z', nargs='?', metavar=('Z1', )),
3905n/a ]
3906n/a argument_group_signatures = []
3907n/a usage = '''\
3908n/a usage: PROG [-h] [-w W1 [W2 ...]] [-x [X1 [X2 ...]]] [-y Y1 Y2 Y3] \
3909n/a[-z [Z1]]
3910n/a '''
3911n/a help = usage + '''\
3912n/a
3913n/a optional arguments:
3914n/a -h, --help show this help message and exit
3915n/a -w W1 [W2 ...] w
3916n/a -x [X1 [X2 ...]] x
3917n/a -y Y1 Y2 Y3 y
3918n/a -z [Z1] z
3919n/a '''
3920n/a version = ''
3921n/a
3922n/a
3923n/aclass TestHelpRawText(HelpTestCase):
3924n/a """Test the RawTextHelpFormatter"""
3925n/a
3926n/a parser_signature = Sig(
3927n/a prog='PROG', formatter_class=argparse.RawTextHelpFormatter,
3928n/a description='Keep the formatting\n'
3929n/a ' exactly as it is written\n'
3930n/a '\n'
3931n/a 'here\n')
3932n/a
3933n/a argument_signatures = [
3934n/a Sig('--foo', help=' foo help should also\n'
3935n/a 'appear as given here'),
3936n/a Sig('spam', help='spam help'),
3937n/a ]
3938n/a argument_group_signatures = [
3939n/a (Sig('title', description=' This text\n'
3940n/a ' should be indented\n'
3941n/a ' exactly like it is here\n'),
3942n/a [Sig('--bar', help='bar help')]),
3943n/a ]
3944n/a usage = '''\
3945n/a usage: PROG [-h] [--foo FOO] [--bar BAR] spam
3946n/a '''
3947n/a help = usage + '''\
3948n/a
3949n/a Keep the formatting
3950n/a exactly as it is written
3951n/a
3952n/a here
3953n/a
3954n/a positional arguments:
3955n/a spam spam help
3956n/a
3957n/a optional arguments:
3958n/a -h, --help show this help message and exit
3959n/a --foo FOO foo help should also
3960n/a appear as given here
3961n/a
3962n/a title:
3963n/a This text
3964n/a should be indented
3965n/a exactly like it is here
3966n/a
3967n/a --bar BAR bar help
3968n/a '''
3969n/a version = ''
3970n/a
3971n/a
3972n/aclass TestHelpRawDescription(HelpTestCase):
3973n/a """Test the RawTextHelpFormatter"""
3974n/a
3975n/a parser_signature = Sig(
3976n/a prog='PROG', formatter_class=argparse.RawDescriptionHelpFormatter,
3977n/a description='Keep the formatting\n'
3978n/a ' exactly as it is written\n'
3979n/a '\n'
3980n/a 'here\n')
3981n/a
3982n/a argument_signatures = [
3983n/a Sig('--foo', help=' foo help should not\n'
3984n/a ' retain this odd formatting'),
3985n/a Sig('spam', help='spam help'),
3986n/a ]
3987n/a argument_group_signatures = [
3988n/a (Sig('title', description=' This text\n'
3989n/a ' should be indented\n'
3990n/a ' exactly like it is here\n'),
3991n/a [Sig('--bar', help='bar help')]),
3992n/a ]
3993n/a usage = '''\
3994n/a usage: PROG [-h] [--foo FOO] [--bar BAR] spam
3995n/a '''
3996n/a help = usage + '''\
3997n/a
3998n/a Keep the formatting
3999n/a exactly as it is written
4000n/a
4001n/a here
4002n/a
4003n/a positional arguments:
4004n/a spam spam help
4005n/a
4006n/a optional arguments:
4007n/a -h, --help show this help message and exit
4008n/a --foo FOO foo help should not retain this odd formatting
4009n/a
4010n/a title:
4011n/a This text
4012n/a should be indented
4013n/a exactly like it is here
4014n/a
4015n/a --bar BAR bar help
4016n/a '''
4017n/a version = ''
4018n/a
4019n/a
4020n/aclass TestHelpArgumentDefaults(HelpTestCase):
4021n/a """Test the ArgumentDefaultsHelpFormatter"""
4022n/a
4023n/a parser_signature = Sig(
4024n/a prog='PROG', formatter_class=argparse.ArgumentDefaultsHelpFormatter,
4025n/a description='description')
4026n/a
4027n/a argument_signatures = [
4028n/a Sig('--foo', help='foo help - oh and by the way, %(default)s'),
4029n/a Sig('--bar', action='store_true', help='bar help'),
4030n/a Sig('spam', help='spam help'),
4031n/a Sig('badger', nargs='?', default='wooden', help='badger help'),
4032n/a ]
4033n/a argument_group_signatures = [
4034n/a (Sig('title', description='description'),
4035n/a [Sig('--baz', type=int, default=42, help='baz help')]),
4036n/a ]
4037n/a usage = '''\
4038n/a usage: PROG [-h] [--foo FOO] [--bar] [--baz BAZ] spam [badger]
4039n/a '''
4040n/a help = usage + '''\
4041n/a
4042n/a description
4043n/a
4044n/a positional arguments:
4045n/a spam spam help
4046n/a badger badger help (default: wooden)
4047n/a
4048n/a optional arguments:
4049n/a -h, --help show this help message and exit
4050n/a --foo FOO foo help - oh and by the way, None
4051n/a --bar bar help (default: False)
4052n/a
4053n/a title:
4054n/a description
4055n/a
4056n/a --baz BAZ baz help (default: 42)
4057n/a '''
4058n/a version = ''
4059n/a
4060n/aclass TestHelpVersionAction(HelpTestCase):
4061n/a """Test the default help for the version action"""
4062n/a
4063n/a parser_signature = Sig(prog='PROG', description='description')
4064n/a argument_signatures = [Sig('-V', '--version', action='version', version='3.6')]
4065n/a argument_group_signatures = []
4066n/a usage = '''\
4067n/a usage: PROG [-h] [-V]
4068n/a '''
4069n/a help = usage + '''\
4070n/a
4071n/a description
4072n/a
4073n/a optional arguments:
4074n/a -h, --help show this help message and exit
4075n/a -V, --version show program's version number and exit
4076n/a '''
4077n/a version = ''
4078n/a
4079n/a
4080n/aclass TestHelpVersionActionSuppress(HelpTestCase):
4081n/a """Test that the --version argument can be suppressed in help messages"""
4082n/a
4083n/a parser_signature = Sig(prog='PROG')
4084n/a argument_signatures = [
4085n/a Sig('-v', '--version', action='version', version='1.0',
4086n/a help=argparse.SUPPRESS),
4087n/a Sig('--foo', help='foo help'),
4088n/a Sig('spam', help='spam help'),
4089n/a ]
4090n/a argument_group_signatures = []
4091n/a usage = '''\
4092n/a usage: PROG [-h] [--foo FOO] spam
4093n/a '''
4094n/a help = usage + '''\
4095n/a
4096n/a positional arguments:
4097n/a spam spam help
4098n/a
4099n/a optional arguments:
4100n/a -h, --help show this help message and exit
4101n/a --foo FOO foo help
4102n/a '''
4103n/a
4104n/a
4105n/aclass TestHelpSubparsersOrdering(HelpTestCase):
4106n/a """Test ordering of subcommands in help matches the code"""
4107n/a parser_signature = Sig(prog='PROG',
4108n/a description='display some subcommands')
4109n/a argument_signatures = [Sig('-v', '--version', action='version', version='0.1')]
4110n/a
4111n/a subparsers_signatures = [Sig(name=name)
4112n/a for name in ('a', 'b', 'c', 'd', 'e')]
4113n/a
4114n/a usage = '''\
4115n/a usage: PROG [-h] [-v] {a,b,c,d,e} ...
4116n/a '''
4117n/a
4118n/a help = usage + '''\
4119n/a
4120n/a display some subcommands
4121n/a
4122n/a positional arguments:
4123n/a {a,b,c,d,e}
4124n/a
4125n/a optional arguments:
4126n/a -h, --help show this help message and exit
4127n/a -v, --version show program's version number and exit
4128n/a '''
4129n/a
4130n/a version = '''\
4131n/a 0.1
4132n/a '''
4133n/a
4134n/aclass TestHelpSubparsersWithHelpOrdering(HelpTestCase):
4135n/a """Test ordering of subcommands in help matches the code"""
4136n/a parser_signature = Sig(prog='PROG',
4137n/a description='display some subcommands')
4138n/a argument_signatures = [Sig('-v', '--version', action='version', version='0.1')]
4139n/a
4140n/a subcommand_data = (('a', 'a subcommand help'),
4141n/a ('b', 'b subcommand help'),
4142n/a ('c', 'c subcommand help'),
4143n/a ('d', 'd subcommand help'),
4144n/a ('e', 'e subcommand help'),
4145n/a )
4146n/a
4147n/a subparsers_signatures = [Sig(name=name, help=help)
4148n/a for name, help in subcommand_data]
4149n/a
4150n/a usage = '''\
4151n/a usage: PROG [-h] [-v] {a,b,c,d,e} ...
4152n/a '''
4153n/a
4154n/a help = usage + '''\
4155n/a
4156n/a display some subcommands
4157n/a
4158n/a positional arguments:
4159n/a {a,b,c,d,e}
4160n/a a a subcommand help
4161n/a b b subcommand help
4162n/a c c subcommand help
4163n/a d d subcommand help
4164n/a e e subcommand help
4165n/a
4166n/a optional arguments:
4167n/a -h, --help show this help message and exit
4168n/a -v, --version show program's version number and exit
4169n/a '''
4170n/a
4171n/a version = '''\
4172n/a 0.1
4173n/a '''
4174n/a
4175n/a
4176n/a
4177n/aclass TestHelpMetavarTypeFormatter(HelpTestCase):
4178n/a """"""
4179n/a
4180n/a def custom_type(string):
4181n/a return string
4182n/a
4183n/a parser_signature = Sig(prog='PROG', description='description',
4184n/a formatter_class=argparse.MetavarTypeHelpFormatter)
4185n/a argument_signatures = [Sig('a', type=int),
4186n/a Sig('-b', type=custom_type),
4187n/a Sig('-c', type=float, metavar='SOME FLOAT')]
4188n/a argument_group_signatures = []
4189n/a usage = '''\
4190n/a usage: PROG [-h] [-b custom_type] [-c SOME FLOAT] int
4191n/a '''
4192n/a help = usage + '''\
4193n/a
4194n/a description
4195n/a
4196n/a positional arguments:
4197n/a int
4198n/a
4199n/a optional arguments:
4200n/a -h, --help show this help message and exit
4201n/a -b custom_type
4202n/a -c SOME FLOAT
4203n/a '''
4204n/a version = ''
4205n/a
4206n/a
4207n/a# =====================================
4208n/a# Optional/Positional constructor tests
4209n/a# =====================================
4210n/a
4211n/aclass TestInvalidArgumentConstructors(TestCase):
4212n/a """Test a bunch of invalid Argument constructors"""
4213n/a
4214n/a def assertTypeError(self, *args, **kwargs):
4215n/a parser = argparse.ArgumentParser()
4216n/a self.assertRaises(TypeError, parser.add_argument,
4217n/a *args, **kwargs)
4218n/a
4219n/a def assertValueError(self, *args, **kwargs):
4220n/a parser = argparse.ArgumentParser()
4221n/a self.assertRaises(ValueError, parser.add_argument,
4222n/a *args, **kwargs)
4223n/a
4224n/a def test_invalid_keyword_arguments(self):
4225n/a self.assertTypeError('-x', bar=None)
4226n/a self.assertTypeError('-y', callback='foo')
4227n/a self.assertTypeError('-y', callback_args=())
4228n/a self.assertTypeError('-y', callback_kwargs={})
4229n/a
4230n/a def test_missing_destination(self):
4231n/a self.assertTypeError()
4232n/a for action in ['append', 'store']:
4233n/a self.assertTypeError(action=action)
4234n/a
4235n/a def test_invalid_option_strings(self):
4236n/a self.assertValueError('--')
4237n/a self.assertValueError('---')
4238n/a
4239n/a def test_invalid_type(self):
4240n/a self.assertValueError('--foo', type='int')
4241n/a self.assertValueError('--foo', type=(int, float))
4242n/a
4243n/a def test_invalid_action(self):
4244n/a self.assertValueError('-x', action='foo')
4245n/a self.assertValueError('foo', action='baz')
4246n/a self.assertValueError('--foo', action=('store', 'append'))
4247n/a parser = argparse.ArgumentParser()
4248n/a with self.assertRaises(ValueError) as cm:
4249n/a parser.add_argument("--foo", action="store-true")
4250n/a self.assertIn('unknown action', str(cm.exception))
4251n/a
4252n/a def test_multiple_dest(self):
4253n/a parser = argparse.ArgumentParser()
4254n/a parser.add_argument(dest='foo')
4255n/a with self.assertRaises(ValueError) as cm:
4256n/a parser.add_argument('bar', dest='baz')
4257n/a self.assertIn('dest supplied twice for positional argument',
4258n/a str(cm.exception))
4259n/a
4260n/a def test_no_argument_actions(self):
4261n/a for action in ['store_const', 'store_true', 'store_false',
4262n/a 'append_const', 'count']:
4263n/a for attrs in [dict(type=int), dict(nargs='+'),
4264n/a dict(choices='ab')]:
4265n/a self.assertTypeError('-x', action=action, **attrs)
4266n/a
4267n/a def test_no_argument_no_const_actions(self):
4268n/a # options with zero arguments
4269n/a for action in ['store_true', 'store_false', 'count']:
4270n/a
4271n/a # const is always disallowed
4272n/a self.assertTypeError('-x', const='foo', action=action)
4273n/a
4274n/a # nargs is always disallowed
4275n/a self.assertTypeError('-x', nargs='*', action=action)
4276n/a
4277n/a def test_more_than_one_argument_actions(self):
4278n/a for action in ['store', 'append']:
4279n/a
4280n/a # nargs=0 is disallowed
4281n/a self.assertValueError('-x', nargs=0, action=action)
4282n/a self.assertValueError('spam', nargs=0, action=action)
4283n/a
4284n/a # const is disallowed with non-optional arguments
4285n/a for nargs in [1, '*', '+']:
4286n/a self.assertValueError('-x', const='foo',
4287n/a nargs=nargs, action=action)
4288n/a self.assertValueError('spam', const='foo',
4289n/a nargs=nargs, action=action)
4290n/a
4291n/a def test_required_const_actions(self):
4292n/a for action in ['store_const', 'append_const']:
4293n/a
4294n/a # nargs is always disallowed
4295n/a self.assertTypeError('-x', nargs='+', action=action)
4296n/a
4297n/a def test_parsers_action_missing_params(self):
4298n/a self.assertTypeError('command', action='parsers')
4299n/a self.assertTypeError('command', action='parsers', prog='PROG')
4300n/a self.assertTypeError('command', action='parsers',
4301n/a parser_class=argparse.ArgumentParser)
4302n/a
4303n/a def test_required_positional(self):
4304n/a self.assertTypeError('foo', required=True)
4305n/a
4306n/a def test_user_defined_action(self):
4307n/a
4308n/a class Success(Exception):
4309n/a pass
4310n/a
4311n/a class Action(object):
4312n/a
4313n/a def __init__(self,
4314n/a option_strings,
4315n/a dest,
4316n/a const,
4317n/a default,
4318n/a required=False):
4319n/a if dest == 'spam':
4320n/a if const is Success:
4321n/a if default is Success:
4322n/a raise Success()
4323n/a
4324n/a def __call__(self, *args, **kwargs):
4325n/a pass
4326n/a
4327n/a parser = argparse.ArgumentParser()
4328n/a self.assertRaises(Success, parser.add_argument, '--spam',
4329n/a action=Action, default=Success, const=Success)
4330n/a self.assertRaises(Success, parser.add_argument, 'spam',
4331n/a action=Action, default=Success, const=Success)
4332n/a
4333n/a# ================================
4334n/a# Actions returned by add_argument
4335n/a# ================================
4336n/a
4337n/aclass TestActionsReturned(TestCase):
4338n/a
4339n/a def test_dest(self):
4340n/a parser = argparse.ArgumentParser()
4341n/a action = parser.add_argument('--foo')
4342n/a self.assertEqual(action.dest, 'foo')
4343n/a action = parser.add_argument('-b', '--bar')
4344n/a self.assertEqual(action.dest, 'bar')
4345n/a action = parser.add_argument('-x', '-y')
4346n/a self.assertEqual(action.dest, 'x')
4347n/a
4348n/a def test_misc(self):
4349n/a parser = argparse.ArgumentParser()
4350n/a action = parser.add_argument('--foo', nargs='?', const=42,
4351n/a default=84, type=int, choices=[1, 2],
4352n/a help='FOO', metavar='BAR', dest='baz')
4353n/a self.assertEqual(action.nargs, '?')
4354n/a self.assertEqual(action.const, 42)
4355n/a self.assertEqual(action.default, 84)
4356n/a self.assertEqual(action.type, int)
4357n/a self.assertEqual(action.choices, [1, 2])
4358n/a self.assertEqual(action.help, 'FOO')
4359n/a self.assertEqual(action.metavar, 'BAR')
4360n/a self.assertEqual(action.dest, 'baz')
4361n/a
4362n/a
4363n/a# ================================
4364n/a# Argument conflict handling tests
4365n/a# ================================
4366n/a
4367n/aclass TestConflictHandling(TestCase):
4368n/a
4369n/a def test_bad_type(self):
4370n/a self.assertRaises(ValueError, argparse.ArgumentParser,
4371n/a conflict_handler='foo')
4372n/a
4373n/a def test_conflict_error(self):
4374n/a parser = argparse.ArgumentParser()
4375n/a parser.add_argument('-x')
4376n/a self.assertRaises(argparse.ArgumentError,
4377n/a parser.add_argument, '-x')
4378n/a parser.add_argument('--spam')
4379n/a self.assertRaises(argparse.ArgumentError,
4380n/a parser.add_argument, '--spam')
4381n/a
4382n/a def test_resolve_error(self):
4383n/a get_parser = argparse.ArgumentParser
4384n/a parser = get_parser(prog='PROG', conflict_handler='resolve')
4385n/a
4386n/a parser.add_argument('-x', help='OLD X')
4387n/a parser.add_argument('-x', help='NEW X')
4388n/a self.assertEqual(parser.format_help(), textwrap.dedent('''\
4389n/a usage: PROG [-h] [-x X]
4390n/a
4391n/a optional arguments:
4392n/a -h, --help show this help message and exit
4393n/a -x X NEW X
4394n/a '''))
4395n/a
4396n/a parser.add_argument('--spam', metavar='OLD_SPAM')
4397n/a parser.add_argument('--spam', metavar='NEW_SPAM')
4398n/a self.assertEqual(parser.format_help(), textwrap.dedent('''\
4399n/a usage: PROG [-h] [-x X] [--spam NEW_SPAM]
4400n/a
4401n/a optional arguments:
4402n/a -h, --help show this help message and exit
4403n/a -x X NEW X
4404n/a --spam NEW_SPAM
4405n/a '''))
4406n/a
4407n/a
4408n/a# =============================
4409n/a# Help and Version option tests
4410n/a# =============================
4411n/a
4412n/aclass TestOptionalsHelpVersionActions(TestCase):
4413n/a """Test the help and version actions"""
4414n/a
4415n/a def assertPrintHelpExit(self, parser, args_str):
4416n/a with self.assertRaises(ArgumentParserError) as cm:
4417n/a parser.parse_args(args_str.split())
4418n/a self.assertEqual(parser.format_help(), cm.exception.stdout)
4419n/a
4420n/a def assertArgumentParserError(self, parser, *args):
4421n/a self.assertRaises(ArgumentParserError, parser.parse_args, args)
4422n/a
4423n/a def test_version(self):
4424n/a parser = ErrorRaisingArgumentParser()
4425n/a parser.add_argument('-v', '--version', action='version', version='1.0')
4426n/a self.assertPrintHelpExit(parser, '-h')
4427n/a self.assertPrintHelpExit(parser, '--help')
4428n/a self.assertRaises(AttributeError, getattr, parser, 'format_version')
4429n/a
4430n/a def test_version_format(self):
4431n/a parser = ErrorRaisingArgumentParser(prog='PPP')
4432n/a parser.add_argument('-v', '--version', action='version', version='%(prog)s 3.5')
4433n/a with self.assertRaises(ArgumentParserError) as cm:
4434n/a parser.parse_args(['-v'])
4435n/a self.assertEqual('PPP 3.5\n', cm.exception.stdout)
4436n/a
4437n/a def test_version_no_help(self):
4438n/a parser = ErrorRaisingArgumentParser(add_help=False)
4439n/a parser.add_argument('-v', '--version', action='version', version='1.0')
4440n/a self.assertArgumentParserError(parser, '-h')
4441n/a self.assertArgumentParserError(parser, '--help')
4442n/a self.assertRaises(AttributeError, getattr, parser, 'format_version')
4443n/a
4444n/a def test_version_action(self):
4445n/a parser = ErrorRaisingArgumentParser(prog='XXX')
4446n/a parser.add_argument('-V', action='version', version='%(prog)s 3.7')
4447n/a with self.assertRaises(ArgumentParserError) as cm:
4448n/a parser.parse_args(['-V'])
4449n/a self.assertEqual('XXX 3.7\n', cm.exception.stdout)
4450n/a
4451n/a def test_no_help(self):
4452n/a parser = ErrorRaisingArgumentParser(add_help=False)
4453n/a self.assertArgumentParserError(parser, '-h')
4454n/a self.assertArgumentParserError(parser, '--help')
4455n/a self.assertArgumentParserError(parser, '-v')
4456n/a self.assertArgumentParserError(parser, '--version')
4457n/a
4458n/a def test_alternate_help_version(self):
4459n/a parser = ErrorRaisingArgumentParser()
4460n/a parser.add_argument('-x', action='help')
4461n/a parser.add_argument('-y', action='version')
4462n/a self.assertPrintHelpExit(parser, '-x')
4463n/a self.assertArgumentParserError(parser, '-v')
4464n/a self.assertArgumentParserError(parser, '--version')
4465n/a self.assertRaises(AttributeError, getattr, parser, 'format_version')
4466n/a
4467n/a def test_help_version_extra_arguments(self):
4468n/a parser = ErrorRaisingArgumentParser()
4469n/a parser.add_argument('--version', action='version', version='1.0')
4470n/a parser.add_argument('-x', action='store_true')
4471n/a parser.add_argument('y')
4472n/a
4473n/a # try all combinations of valid prefixes and suffixes
4474n/a valid_prefixes = ['', '-x', 'foo', '-x bar', 'baz -x']
4475n/a valid_suffixes = valid_prefixes + ['--bad-option', 'foo bar baz']
4476n/a for prefix in valid_prefixes:
4477n/a for suffix in valid_suffixes:
4478n/a format = '%s %%s %s' % (prefix, suffix)
4479n/a self.assertPrintHelpExit(parser, format % '-h')
4480n/a self.assertPrintHelpExit(parser, format % '--help')
4481n/a self.assertRaises(AttributeError, getattr, parser, 'format_version')
4482n/a
4483n/a
4484n/a# ======================
4485n/a# str() and repr() tests
4486n/a# ======================
4487n/a
4488n/aclass TestStrings(TestCase):
4489n/a """Test str() and repr() on Optionals and Positionals"""
4490n/a
4491n/a def assertStringEqual(self, obj, result_string):
4492n/a for func in [str, repr]:
4493n/a self.assertEqual(func(obj), result_string)
4494n/a
4495n/a def test_optional(self):
4496n/a option = argparse.Action(
4497n/a option_strings=['--foo', '-a', '-b'],
4498n/a dest='b',
4499n/a type='int',
4500n/a nargs='+',
4501n/a default=42,
4502n/a choices=[1, 2, 3],
4503n/a help='HELP',
4504n/a metavar='METAVAR')
4505n/a string = (
4506n/a "Action(option_strings=['--foo', '-a', '-b'], dest='b', "
4507n/a "nargs='+', const=None, default=42, type='int', "
4508n/a "choices=[1, 2, 3], help='HELP', metavar='METAVAR')")
4509n/a self.assertStringEqual(option, string)
4510n/a
4511n/a def test_argument(self):
4512n/a argument = argparse.Action(
4513n/a option_strings=[],
4514n/a dest='x',
4515n/a type=float,
4516n/a nargs='?',
4517n/a default=2.5,
4518n/a choices=[0.5, 1.5, 2.5],
4519n/a help='H HH H',
4520n/a metavar='MV MV MV')
4521n/a string = (
4522n/a "Action(option_strings=[], dest='x', nargs='?', "
4523n/a "const=None, default=2.5, type=%r, choices=[0.5, 1.5, 2.5], "
4524n/a "help='H HH H', metavar='MV MV MV')" % float)
4525n/a self.assertStringEqual(argument, string)
4526n/a
4527n/a def test_namespace(self):
4528n/a ns = argparse.Namespace(foo=42, bar='spam')
4529n/a string = "Namespace(bar='spam', foo=42)"
4530n/a self.assertStringEqual(ns, string)
4531n/a
4532n/a def test_namespace_starkwargs_notidentifier(self):
4533n/a ns = argparse.Namespace(**{'"': 'quote'})
4534n/a string = """Namespace(**{'"': 'quote'})"""
4535n/a self.assertStringEqual(ns, string)
4536n/a
4537n/a def test_namespace_kwargs_and_starkwargs_notidentifier(self):
4538n/a ns = argparse.Namespace(a=1, **{'"': 'quote'})
4539n/a string = """Namespace(a=1, **{'"': 'quote'})"""
4540n/a self.assertStringEqual(ns, string)
4541n/a
4542n/a def test_namespace_starkwargs_identifier(self):
4543n/a ns = argparse.Namespace(**{'valid': True})
4544n/a string = "Namespace(valid=True)"
4545n/a self.assertStringEqual(ns, string)
4546n/a
4547n/a def test_parser(self):
4548n/a parser = argparse.ArgumentParser(prog='PROG')
4549n/a string = (
4550n/a "ArgumentParser(prog='PROG', usage=None, description=None, "
4551n/a "formatter_class=%r, conflict_handler='error', "
4552n/a "add_help=True)" % argparse.HelpFormatter)
4553n/a self.assertStringEqual(parser, string)
4554n/a
4555n/a# ===============
4556n/a# Namespace tests
4557n/a# ===============
4558n/a
4559n/aclass TestNamespace(TestCase):
4560n/a
4561n/a def test_constructor(self):
4562n/a ns = argparse.Namespace()
4563n/a self.assertRaises(AttributeError, getattr, ns, 'x')
4564n/a
4565n/a ns = argparse.Namespace(a=42, b='spam')
4566n/a self.assertEqual(ns.a, 42)
4567n/a self.assertEqual(ns.b, 'spam')
4568n/a
4569n/a def test_equality(self):
4570n/a ns1 = argparse.Namespace(a=1, b=2)
4571n/a ns2 = argparse.Namespace(b=2, a=1)
4572n/a ns3 = argparse.Namespace(a=1)
4573n/a ns4 = argparse.Namespace(b=2)
4574n/a
4575n/a self.assertEqual(ns1, ns2)
4576n/a self.assertNotEqual(ns1, ns3)
4577n/a self.assertNotEqual(ns1, ns4)
4578n/a self.assertNotEqual(ns2, ns3)
4579n/a self.assertNotEqual(ns2, ns4)
4580n/a self.assertTrue(ns1 != ns3)
4581n/a self.assertTrue(ns1 != ns4)
4582n/a self.assertTrue(ns2 != ns3)
4583n/a self.assertTrue(ns2 != ns4)
4584n/a
4585n/a def test_equality_returns_notimplemented(self):
4586n/a # See issue 21481
4587n/a ns = argparse.Namespace(a=1, b=2)
4588n/a self.assertIs(ns.__eq__(None), NotImplemented)
4589n/a self.assertIs(ns.__ne__(None), NotImplemented)
4590n/a
4591n/a
4592n/a# ===================
4593n/a# File encoding tests
4594n/a# ===================
4595n/a
4596n/aclass TestEncoding(TestCase):
4597n/a
4598n/a def _test_module_encoding(self, path):
4599n/a path, _ = os.path.splitext(path)
4600n/a path += ".py"
4601n/a with codecs.open(path, 'r', 'utf-8') as f:
4602n/a f.read()
4603n/a
4604n/a def test_argparse_module_encoding(self):
4605n/a self._test_module_encoding(argparse.__file__)
4606n/a
4607n/a def test_test_argparse_module_encoding(self):
4608n/a self._test_module_encoding(__file__)
4609n/a
4610n/a# ===================
4611n/a# ArgumentError tests
4612n/a# ===================
4613n/a
4614n/aclass TestArgumentError(TestCase):
4615n/a
4616n/a def test_argument_error(self):
4617n/a msg = "my error here"
4618n/a error = argparse.ArgumentError(None, msg)
4619n/a self.assertEqual(str(error), msg)
4620n/a
4621n/a# =======================
4622n/a# ArgumentTypeError tests
4623n/a# =======================
4624n/a
4625n/aclass TestArgumentTypeError(TestCase):
4626n/a
4627n/a def test_argument_type_error(self):
4628n/a
4629n/a def spam(string):
4630n/a raise argparse.ArgumentTypeError('spam!')
4631n/a
4632n/a parser = ErrorRaisingArgumentParser(prog='PROG', add_help=False)
4633n/a parser.add_argument('x', type=spam)
4634n/a with self.assertRaises(ArgumentParserError) as cm:
4635n/a parser.parse_args(['XXX'])
4636n/a self.assertEqual('usage: PROG x\nPROG: error: argument x: spam!\n',
4637n/a cm.exception.stderr)
4638n/a
4639n/a# =========================
4640n/a# MessageContentError tests
4641n/a# =========================
4642n/a
4643n/aclass TestMessageContentError(TestCase):
4644n/a
4645n/a def test_missing_argument_name_in_message(self):
4646n/a parser = ErrorRaisingArgumentParser(prog='PROG', usage='')
4647n/a parser.add_argument('req_pos', type=str)
4648n/a parser.add_argument('-req_opt', type=int, required=True)
4649n/a parser.add_argument('need_one', type=str, nargs='+')
4650n/a
4651n/a with self.assertRaises(ArgumentParserError) as cm:
4652n/a parser.parse_args([])
4653n/a msg = str(cm.exception)
4654n/a self.assertRegex(msg, 'req_pos')
4655n/a self.assertRegex(msg, 'req_opt')
4656n/a self.assertRegex(msg, 'need_one')
4657n/a with self.assertRaises(ArgumentParserError) as cm:
4658n/a parser.parse_args(['myXargument'])
4659n/a msg = str(cm.exception)
4660n/a self.assertNotIn(msg, 'req_pos')
4661n/a self.assertRegex(msg, 'req_opt')
4662n/a self.assertRegex(msg, 'need_one')
4663n/a with self.assertRaises(ArgumentParserError) as cm:
4664n/a parser.parse_args(['myXargument', '-req_opt=1'])
4665n/a msg = str(cm.exception)
4666n/a self.assertNotIn(msg, 'req_pos')
4667n/a self.assertNotIn(msg, 'req_opt')
4668n/a self.assertRegex(msg, 'need_one')
4669n/a
4670n/a def test_optional_optional_not_in_message(self):
4671n/a parser = ErrorRaisingArgumentParser(prog='PROG', usage='')
4672n/a parser.add_argument('req_pos', type=str)
4673n/a parser.add_argument('--req_opt', type=int, required=True)
4674n/a parser.add_argument('--opt_opt', type=bool, nargs='?',
4675n/a default=True)
4676n/a with self.assertRaises(ArgumentParserError) as cm:
4677n/a parser.parse_args([])
4678n/a msg = str(cm.exception)
4679n/a self.assertRegex(msg, 'req_pos')
4680n/a self.assertRegex(msg, 'req_opt')
4681n/a self.assertNotIn(msg, 'opt_opt')
4682n/a with self.assertRaises(ArgumentParserError) as cm:
4683n/a parser.parse_args(['--req_opt=1'])
4684n/a msg = str(cm.exception)
4685n/a self.assertRegex(msg, 'req_pos')
4686n/a self.assertNotIn(msg, 'req_opt')
4687n/a self.assertNotIn(msg, 'opt_opt')
4688n/a
4689n/a def test_optional_positional_not_in_message(self):
4690n/a parser = ErrorRaisingArgumentParser(prog='PROG', usage='')
4691n/a parser.add_argument('req_pos')
4692n/a parser.add_argument('optional_positional', nargs='?', default='eggs')
4693n/a with self.assertRaises(ArgumentParserError) as cm:
4694n/a parser.parse_args([])
4695n/a msg = str(cm.exception)
4696n/a self.assertRegex(msg, 'req_pos')
4697n/a self.assertNotIn(msg, 'optional_positional')
4698n/a
4699n/a
4700n/a# ================================================
4701n/a# Check that the type function is called only once
4702n/a# ================================================
4703n/a
4704n/aclass TestTypeFunctionCallOnlyOnce(TestCase):
4705n/a
4706n/a def test_type_function_call_only_once(self):
4707n/a def spam(string_to_convert):
4708n/a self.assertEqual(string_to_convert, 'spam!')
4709n/a return 'foo_converted'
4710n/a
4711n/a parser = argparse.ArgumentParser()
4712n/a parser.add_argument('--foo', type=spam, default='bar')
4713n/a args = parser.parse_args('--foo spam!'.split())
4714n/a self.assertEqual(NS(foo='foo_converted'), args)
4715n/a
4716n/a# ==================================================================
4717n/a# Check semantics regarding the default argument and type conversion
4718n/a# ==================================================================
4719n/a
4720n/aclass TestTypeFunctionCalledOnDefault(TestCase):
4721n/a
4722n/a def test_type_function_call_with_non_string_default(self):
4723n/a def spam(int_to_convert):
4724n/a self.assertEqual(int_to_convert, 0)
4725n/a return 'foo_converted'
4726n/a
4727n/a parser = argparse.ArgumentParser()
4728n/a parser.add_argument('--foo', type=spam, default=0)
4729n/a args = parser.parse_args([])
4730n/a # foo should *not* be converted because its default is not a string.
4731n/a self.assertEqual(NS(foo=0), args)
4732n/a
4733n/a def test_type_function_call_with_string_default(self):
4734n/a def spam(int_to_convert):
4735n/a return 'foo_converted'
4736n/a
4737n/a parser = argparse.ArgumentParser()
4738n/a parser.add_argument('--foo', type=spam, default='0')
4739n/a args = parser.parse_args([])
4740n/a # foo is converted because its default is a string.
4741n/a self.assertEqual(NS(foo='foo_converted'), args)
4742n/a
4743n/a def test_no_double_type_conversion_of_default(self):
4744n/a def extend(str_to_convert):
4745n/a return str_to_convert + '*'
4746n/a
4747n/a parser = argparse.ArgumentParser()
4748n/a parser.add_argument('--test', type=extend, default='*')
4749n/a args = parser.parse_args([])
4750n/a # The test argument will be two stars, one coming from the default
4751n/a # value and one coming from the type conversion being called exactly
4752n/a # once.
4753n/a self.assertEqual(NS(test='**'), args)
4754n/a
4755n/a def test_issue_15906(self):
4756n/a # Issue #15906: When action='append', type=str, default=[] are
4757n/a # providing, the dest value was the string representation "[]" when it
4758n/a # should have been an empty list.
4759n/a parser = argparse.ArgumentParser()
4760n/a parser.add_argument('--test', dest='test', type=str,
4761n/a default=[], action='append')
4762n/a args = parser.parse_args([])
4763n/a self.assertEqual(args.test, [])
4764n/a
4765n/a# ======================
4766n/a# parse_known_args tests
4767n/a# ======================
4768n/a
4769n/aclass TestParseKnownArgs(TestCase):
4770n/a
4771n/a def test_arguments_tuple(self):
4772n/a parser = argparse.ArgumentParser()
4773n/a parser.parse_args(())
4774n/a
4775n/a def test_arguments_list(self):
4776n/a parser = argparse.ArgumentParser()
4777n/a parser.parse_args([])
4778n/a
4779n/a def test_arguments_tuple_positional(self):
4780n/a parser = argparse.ArgumentParser()
4781n/a parser.add_argument('x')
4782n/a parser.parse_args(('x',))
4783n/a
4784n/a def test_arguments_list_positional(self):
4785n/a parser = argparse.ArgumentParser()
4786n/a parser.add_argument('x')
4787n/a parser.parse_args(['x'])
4788n/a
4789n/a def test_optionals(self):
4790n/a parser = argparse.ArgumentParser()
4791n/a parser.add_argument('--foo')
4792n/a args, extras = parser.parse_known_args('--foo F --bar --baz'.split())
4793n/a self.assertEqual(NS(foo='F'), args)
4794n/a self.assertEqual(['--bar', '--baz'], extras)
4795n/a
4796n/a def test_mixed(self):
4797n/a parser = argparse.ArgumentParser()
4798n/a parser.add_argument('-v', nargs='?', const=1, type=int)
4799n/a parser.add_argument('--spam', action='store_false')
4800n/a parser.add_argument('badger')
4801n/a
4802n/a argv = ["B", "C", "--foo", "-v", "3", "4"]
4803n/a args, extras = parser.parse_known_args(argv)
4804n/a self.assertEqual(NS(v=3, spam=True, badger="B"), args)
4805n/a self.assertEqual(["C", "--foo", "4"], extras)
4806n/a
4807n/a# ==========================
4808n/a# add_argument metavar tests
4809n/a# ==========================
4810n/a
4811n/aclass TestAddArgumentMetavar(TestCase):
4812n/a
4813n/a EXPECTED_MESSAGE = "length of metavar tuple does not match nargs"
4814n/a
4815n/a def do_test_no_exception(self, nargs, metavar):
4816n/a parser = argparse.ArgumentParser()
4817n/a parser.add_argument("--foo", nargs=nargs, metavar=metavar)
4818n/a
4819n/a def do_test_exception(self, nargs, metavar):
4820n/a parser = argparse.ArgumentParser()
4821n/a with self.assertRaises(ValueError) as cm:
4822n/a parser.add_argument("--foo", nargs=nargs, metavar=metavar)
4823n/a self.assertEqual(cm.exception.args[0], self.EXPECTED_MESSAGE)
4824n/a
4825n/a # Unit tests for different values of metavar when nargs=None
4826n/a
4827n/a def test_nargs_None_metavar_string(self):
4828n/a self.do_test_no_exception(nargs=None, metavar="1")
4829n/a
4830n/a def test_nargs_None_metavar_length0(self):
4831n/a self.do_test_exception(nargs=None, metavar=tuple())
4832n/a
4833n/a def test_nargs_None_metavar_length1(self):
4834n/a self.do_test_no_exception(nargs=None, metavar=("1"))
4835n/a
4836n/a def test_nargs_None_metavar_length2(self):
4837n/a self.do_test_exception(nargs=None, metavar=("1", "2"))
4838n/a
4839n/a def test_nargs_None_metavar_length3(self):
4840n/a self.do_test_exception(nargs=None, metavar=("1", "2", "3"))
4841n/a
4842n/a # Unit tests for different values of metavar when nargs=?
4843n/a
4844n/a def test_nargs_optional_metavar_string(self):
4845n/a self.do_test_no_exception(nargs="?", metavar="1")
4846n/a
4847n/a def test_nargs_optional_metavar_length0(self):
4848n/a self.do_test_exception(nargs="?", metavar=tuple())
4849n/a
4850n/a def test_nargs_optional_metavar_length1(self):
4851n/a self.do_test_no_exception(nargs="?", metavar=("1"))
4852n/a
4853n/a def test_nargs_optional_metavar_length2(self):
4854n/a self.do_test_exception(nargs="?", metavar=("1", "2"))
4855n/a
4856n/a def test_nargs_optional_metavar_length3(self):
4857n/a self.do_test_exception(nargs="?", metavar=("1", "2", "3"))
4858n/a
4859n/a # Unit tests for different values of metavar when nargs=*
4860n/a
4861n/a def test_nargs_zeroormore_metavar_string(self):
4862n/a self.do_test_no_exception(nargs="*", metavar="1")
4863n/a
4864n/a def test_nargs_zeroormore_metavar_length0(self):
4865n/a self.do_test_exception(nargs="*", metavar=tuple())
4866n/a
4867n/a def test_nargs_zeroormore_metavar_length1(self):
4868n/a self.do_test_no_exception(nargs="*", metavar=("1"))
4869n/a
4870n/a def test_nargs_zeroormore_metavar_length2(self):
4871n/a self.do_test_no_exception(nargs="*", metavar=("1", "2"))
4872n/a
4873n/a def test_nargs_zeroormore_metavar_length3(self):
4874n/a self.do_test_exception(nargs="*", metavar=("1", "2", "3"))
4875n/a
4876n/a # Unit tests for different values of metavar when nargs=+
4877n/a
4878n/a def test_nargs_oneormore_metavar_string(self):
4879n/a self.do_test_no_exception(nargs="+", metavar="1")
4880n/a
4881n/a def test_nargs_oneormore_metavar_length0(self):
4882n/a self.do_test_exception(nargs="+", metavar=tuple())
4883n/a
4884n/a def test_nargs_oneormore_metavar_length1(self):
4885n/a self.do_test_no_exception(nargs="+", metavar=("1"))
4886n/a
4887n/a def test_nargs_oneormore_metavar_length2(self):
4888n/a self.do_test_no_exception(nargs="+", metavar=("1", "2"))
4889n/a
4890n/a def test_nargs_oneormore_metavar_length3(self):
4891n/a self.do_test_exception(nargs="+", metavar=("1", "2", "3"))
4892n/a
4893n/a # Unit tests for different values of metavar when nargs=...
4894n/a
4895n/a def test_nargs_remainder_metavar_string(self):
4896n/a self.do_test_no_exception(nargs="...", metavar="1")
4897n/a
4898n/a def test_nargs_remainder_metavar_length0(self):
4899n/a self.do_test_no_exception(nargs="...", metavar=tuple())
4900n/a
4901n/a def test_nargs_remainder_metavar_length1(self):
4902n/a self.do_test_no_exception(nargs="...", metavar=("1"))
4903n/a
4904n/a def test_nargs_remainder_metavar_length2(self):
4905n/a self.do_test_no_exception(nargs="...", metavar=("1", "2"))
4906n/a
4907n/a def test_nargs_remainder_metavar_length3(self):
4908n/a self.do_test_no_exception(nargs="...", metavar=("1", "2", "3"))
4909n/a
4910n/a # Unit tests for different values of metavar when nargs=A...
4911n/a
4912n/a def test_nargs_parser_metavar_string(self):
4913n/a self.do_test_no_exception(nargs="A...", metavar="1")
4914n/a
4915n/a def test_nargs_parser_metavar_length0(self):
4916n/a self.do_test_exception(nargs="A...", metavar=tuple())
4917n/a
4918n/a def test_nargs_parser_metavar_length1(self):
4919n/a self.do_test_no_exception(nargs="A...", metavar=("1"))
4920n/a
4921n/a def test_nargs_parser_metavar_length2(self):
4922n/a self.do_test_exception(nargs="A...", metavar=("1", "2"))
4923n/a
4924n/a def test_nargs_parser_metavar_length3(self):
4925n/a self.do_test_exception(nargs="A...", metavar=("1", "2", "3"))
4926n/a
4927n/a # Unit tests for different values of metavar when nargs=1
4928n/a
4929n/a def test_nargs_1_metavar_string(self):
4930n/a self.do_test_no_exception(nargs=1, metavar="1")
4931n/a
4932n/a def test_nargs_1_metavar_length0(self):
4933n/a self.do_test_exception(nargs=1, metavar=tuple())
4934n/a
4935n/a def test_nargs_1_metavar_length1(self):
4936n/a self.do_test_no_exception(nargs=1, metavar=("1"))
4937n/a
4938n/a def test_nargs_1_metavar_length2(self):
4939n/a self.do_test_exception(nargs=1, metavar=("1", "2"))
4940n/a
4941n/a def test_nargs_1_metavar_length3(self):
4942n/a self.do_test_exception(nargs=1, metavar=("1", "2", "3"))
4943n/a
4944n/a # Unit tests for different values of metavar when nargs=2
4945n/a
4946n/a def test_nargs_2_metavar_string(self):
4947n/a self.do_test_no_exception(nargs=2, metavar="1")
4948n/a
4949n/a def test_nargs_2_metavar_length0(self):
4950n/a self.do_test_exception(nargs=2, metavar=tuple())
4951n/a
4952n/a def test_nargs_2_metavar_length1(self):
4953n/a self.do_test_no_exception(nargs=2, metavar=("1"))
4954n/a
4955n/a def test_nargs_2_metavar_length2(self):
4956n/a self.do_test_no_exception(nargs=2, metavar=("1", "2"))
4957n/a
4958n/a def test_nargs_2_metavar_length3(self):
4959n/a self.do_test_exception(nargs=2, metavar=("1", "2", "3"))
4960n/a
4961n/a # Unit tests for different values of metavar when nargs=3
4962n/a
4963n/a def test_nargs_3_metavar_string(self):
4964n/a self.do_test_no_exception(nargs=3, metavar="1")
4965n/a
4966n/a def test_nargs_3_metavar_length0(self):
4967n/a self.do_test_exception(nargs=3, metavar=tuple())
4968n/a
4969n/a def test_nargs_3_metavar_length1(self):
4970n/a self.do_test_no_exception(nargs=3, metavar=("1"))
4971n/a
4972n/a def test_nargs_3_metavar_length2(self):
4973n/a self.do_test_exception(nargs=3, metavar=("1", "2"))
4974n/a
4975n/a def test_nargs_3_metavar_length3(self):
4976n/a self.do_test_no_exception(nargs=3, metavar=("1", "2", "3"))
4977n/a
4978n/a# ============================
4979n/a# from argparse import * tests
4980n/a# ============================
4981n/a
4982n/aclass TestImportStar(TestCase):
4983n/a
4984n/a def test(self):
4985n/a for name in argparse.__all__:
4986n/a self.assertTrue(hasattr(argparse, name))
4987n/a
4988n/a def test_all_exports_everything_but_modules(self):
4989n/a items = [
4990n/a name
4991n/a for name, value in vars(argparse).items()
4992n/a if not (name.startswith("_") or name == 'ngettext')
4993n/a if not inspect.ismodule(value)
4994n/a ]
4995n/a self.assertEqual(sorted(items), sorted(argparse.__all__))
4996n/a
4997n/adef test_main():
4998n/a support.run_unittest(__name__)
4999n/a # Remove global references to avoid looking like we have refleaks.
5000n/a RFile.seen = {}
5001n/a WFile.seen = set()
5002n/a
5003n/a
5004n/a
5005n/aif __name__ == '__main__':
5006n/a test_main()