Adds help for subcommands
Adds help subcommand which takes other subcommands as param. Adds -h/--help option for subcommands. This contains integration testing code for tuskar CLI. Following tests are implemented: o bare help command o help command with bad parameter o help command with -h / --help parameter o set of tests for "help <command>", "<command> -h / --help" for following commands: - flavor-create - flavor-delete - flavor-list - flavor-show - flavor-update - rack-create - rack-delete - rack-list - rack-show - rack-update Fixes bug in tests/test_shell.py - {} -> [] Fixes bug: 1213050 Change-Id: Ic554198f4fb4cdbaeefb9831c15f969301a7be87
This commit is contained in:
parent
b389de3544
commit
6c06cbcf01
@ -31,24 +31,42 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
class TuskarShell(object):
|
||||
|
||||
def __init__(self, raw_args):
|
||||
def __init__(self, raw_args,
|
||||
argument_parser_class=argparse.ArgumentParser):
|
||||
self.raw_args = raw_args
|
||||
self.argument_parser_class = argument_parser_class
|
||||
|
||||
self.partial_args = None
|
||||
self.parser = None
|
||||
self.subparsers = None
|
||||
self._prepare_parsers()
|
||||
|
||||
def _prepare_parsers(self):
|
||||
nonversioned_parser = self._nonversioned_parser()
|
||||
self.partial_args =\
|
||||
nonversioned_parser.parse_known_args(self.raw_args)[0]
|
||||
self.parser, self.subparsers =\
|
||||
self._parser(self.partial_args.tuskar_api_version)
|
||||
|
||||
def run(self):
|
||||
'''Run the CLI. Parse arguments and do the respective action.'''
|
||||
|
||||
nonversioned_parser = self._nonversioned_parser()
|
||||
partial_args = nonversioned_parser.parse_known_args(self.raw_args)[0]
|
||||
parser = self._parser(partial_args.tuskar_api_version)
|
||||
|
||||
if partial_args.help or not self.raw_args:
|
||||
parser.print_help()
|
||||
# run self.do_help() if we have no raw_args at all or just -h/--help
|
||||
if not self.raw_args\
|
||||
or self.raw_args in (['-h'], ['--help']):
|
||||
self.do_help(self.partial_args)
|
||||
return 0
|
||||
|
||||
args = self.parser.parse_args(self.raw_args)
|
||||
|
||||
# run self.do_help() if we have help subcommand or -h/--help option
|
||||
if args.func == self.do_help or args.help:
|
||||
self.do_help(args)
|
||||
return 0
|
||||
|
||||
args = parser.parse_args(self.raw_args)
|
||||
self._ensure_auth_info(args)
|
||||
|
||||
tuskar_client = client.get_client(partial_args.tuskar_api_version,
|
||||
tuskar_client = client.get_client(self.partial_args.tuskar_api_version,
|
||||
**args.__dict__)
|
||||
args.func(tuskar_client, args)
|
||||
|
||||
@ -87,12 +105,15 @@ class TuskarShell(object):
|
||||
|
||||
:param version: version of Tuskar API (and corresponding CLI
|
||||
commands) to use
|
||||
:return: main parser and subparsers
|
||||
:rtype: (Parser, Subparsers)
|
||||
'''
|
||||
parser = self._nonversioned_parser()
|
||||
subparsers = parser.add_subparsers(metavar='<subcommand>')
|
||||
versioned_shell = utils.import_versioned_module(version, 'shell')
|
||||
versioned_shell.enhance_parser(parser, subparsers)
|
||||
return parser
|
||||
utils.define_commands_from_module(subparsers, self)
|
||||
return parser, subparsers
|
||||
|
||||
def _nonversioned_parser(self):
|
||||
'''Create a basic parser that doesn't contain version-specific
|
||||
@ -100,10 +121,10 @@ class TuskarShell(object):
|
||||
version should be used for the versioned full blown parser and
|
||||
defining common version-agnostic options.
|
||||
'''
|
||||
parser = argparse.ArgumentParser(
|
||||
parser = self.argument_parser_class(
|
||||
prog='tuskar',
|
||||
description='OpenStack Management CLI',
|
||||
add_help=False
|
||||
add_help=False,
|
||||
)
|
||||
|
||||
parser.add_argument('-h', '--help',
|
||||
@ -181,6 +202,22 @@ class TuskarShell(object):
|
||||
|
||||
return parser
|
||||
|
||||
@utils.arg(
|
||||
'command', metavar='<subcommand>', nargs='?',
|
||||
help='Display help for <subcommand>')
|
||||
def do_help(self, args):
|
||||
"""Display help about this program or one of its subcommands."""
|
||||
if getattr(args, 'command', None):
|
||||
if args.command in self.subparsers.choices:
|
||||
# print help for subcommand
|
||||
self.subparsers.choices[args.command].print_help()
|
||||
else:
|
||||
raise exc.CommandError("'%s' is not a valid subcommand" %
|
||||
args.command)
|
||||
else:
|
||||
# print general help
|
||||
self.parser.print_help()
|
||||
|
||||
|
||||
def main():
|
||||
try:
|
||||
|
0
tuskarclient/tests/integration/__init__.py
Normal file
0
tuskarclient/tests/integration/__init__.py
Normal file
311
tuskarclient/tests/integration/test_help_command.py
Normal file
311
tuskarclient/tests/integration/test_help_command.py
Normal file
@ -0,0 +1,311 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import tuskarclient.tests.utils as tutils
|
||||
|
||||
|
||||
class HelpCommandTest(tutils.CommandTestCase):
|
||||
pass
|
||||
|
||||
tests = [
|
||||
# help
|
||||
{
|
||||
'commands': ['help'], # commands to test "tuskar help"
|
||||
# helps find failed tests in code - needs "test_" prefix
|
||||
'test_identifiers': ['test_help'],
|
||||
'out_includes': [ # what should be in output
|
||||
'usage:',
|
||||
'positional arguments:',
|
||||
'optional arguments:',
|
||||
],
|
||||
'out_excludes': [ # what should not be in output
|
||||
'foo bar baz',
|
||||
],
|
||||
'err_string': '', # how error output should look like
|
||||
'return_code': 0,
|
||||
},
|
||||
{
|
||||
'commands': ['help -h', 'help --help', 'help help'],
|
||||
'test_identifiers': ['test_help_dash_h',
|
||||
'test_help_dashdash_help',
|
||||
'test_help_help'],
|
||||
'out_includes': [
|
||||
'usage:',
|
||||
'positional arguments:',
|
||||
'optional arguments:',
|
||||
'Display help for <subcommand>',
|
||||
],
|
||||
'out_excludes': [
|
||||
'flavor-list',
|
||||
'--os-username OS_USERNAME',
|
||||
],
|
||||
'err_string': '',
|
||||
'return_code': 0,
|
||||
},
|
||||
{
|
||||
'commands': ['help -r'],
|
||||
'test_identifiers': ['test_help_dash_r'],
|
||||
'out_string': '',
|
||||
'err_includes': [
|
||||
'error: unrecognized arguments: -r',
|
||||
],
|
||||
'return_code': 2,
|
||||
},
|
||||
# rack
|
||||
{
|
||||
'commands': ['rack-delete -h',
|
||||
'rack-delete --help',
|
||||
'help rack-delete'],
|
||||
'test_identifiers': ['test_rack_delete_dash_h',
|
||||
'test_rack_delete_dashdash_help',
|
||||
'test_help_rack_delete'],
|
||||
'out_includes': [
|
||||
'usage: tuskar rack-delete [-h] <NAME or ID>',
|
||||
'positional arguments:',
|
||||
'optional arguments:',
|
||||
'<NAME or ID>',
|
||||
],
|
||||
'out_excludes': [
|
||||
'rack-list',
|
||||
'--os-username OS_USERNAME',
|
||||
'Display help for <subcommand>',
|
||||
],
|
||||
'err_string': '',
|
||||
'return_code': 0,
|
||||
},
|
||||
{
|
||||
'commands': ['rack-update -h',
|
||||
'rack-update --help',
|
||||
'help rack-update'],
|
||||
'test_identifiers': ['test_rack_update_dash_h',
|
||||
'test_rack_update_dashdash_help',
|
||||
'test_help_rack_update'],
|
||||
'out_includes': [
|
||||
'usage: tuskar rack-update [-h] [--name NAME] [--subnet SUBNET]',
|
||||
'positional arguments:',
|
||||
'<NAME or ID>',
|
||||
'optional arguments:',
|
||||
'--name NAME',
|
||||
'--subnet SUBNET',
|
||||
'--slots SLOTS',
|
||||
'--capacities CAPACITIES',
|
||||
'--resource-class RESOURCE_CLASS',
|
||||
],
|
||||
'out_excludes': [
|
||||
'rack-list',
|
||||
'--os-username OS_USERNAME',
|
||||
'Display help for <subcommand>',
|
||||
],
|
||||
'err_string': '',
|
||||
'return_code': 0,
|
||||
},
|
||||
{
|
||||
'commands': ['rack-create -h',
|
||||
'rack-create --help',
|
||||
'help rack-create'],
|
||||
'test_identifiers': ['test_rack_create_dash_h',
|
||||
'test_rack_create_dashdash_help',
|
||||
'test_help_rack_create'],
|
||||
'out_includes': [
|
||||
'usage: tuskar rack-create [-h] --subnet SUBNET --slots SLOTS',
|
||||
'positional arguments:',
|
||||
'optional arguments:',
|
||||
'--subnet SUBNET',
|
||||
'--slots SLOTS',
|
||||
'--capacities CAPACITIES',
|
||||
'--resource-class RESOURCE_CLASS',
|
||||
],
|
||||
'out_excludes': [
|
||||
'rack-list',
|
||||
'--os-username OS_USERNAME',
|
||||
'Display help for <subcommand>',
|
||||
],
|
||||
'err_string': '',
|
||||
'return_code': 0,
|
||||
},
|
||||
{
|
||||
'commands': ['rack-show -h', 'rack-show --help', 'help rack-show'],
|
||||
'test_identifiers': ['test_rack_show_dash_h',
|
||||
'test_rack_show_dashdash_help',
|
||||
'test_help_rack_show'],
|
||||
'out_includes': [
|
||||
'usage: tuskar rack-show [-h] <NAME or ID>',
|
||||
'positional arguments:',
|
||||
'optional arguments:',
|
||||
'<NAME or ID>',
|
||||
],
|
||||
'out_excludes': [
|
||||
'rack-list',
|
||||
'--os-username OS_USERNAME',
|
||||
'Display help for <subcommand>',
|
||||
],
|
||||
'err_string': '',
|
||||
'return_code': 0,
|
||||
},
|
||||
{
|
||||
'commands': ['rack-list -h', 'rack-list --help', 'help rack-list'],
|
||||
'test_identifiers': ['test_rack_list_dash_h',
|
||||
'test_rack_list_dashdash_help',
|
||||
'test_help_rack_list'],
|
||||
'out_includes': [
|
||||
'usage: tuskar rack-list [-h]',
|
||||
'optional arguments:',
|
||||
],
|
||||
'out_excludes': [
|
||||
'rack-show',
|
||||
'--os-username OS_USERNAME',
|
||||
'Display help for <subcommand>',
|
||||
'positional arguments:',
|
||||
],
|
||||
'err_string': '',
|
||||
'return_code': 0,
|
||||
},
|
||||
# flavor
|
||||
{
|
||||
'commands': ['flavor-delete -h',
|
||||
'flavor-delete --help',
|
||||
'help flavor-delete'],
|
||||
'test_identifiers': ['test_flavor_delete_dash_h',
|
||||
'test_flavor_delete_dashdash_help',
|
||||
'test_help_flavor_delete'],
|
||||
'out_includes': [
|
||||
'usage: tuskar flavor-delete [-h]',
|
||||
'optional arguments:',
|
||||
'positional arguments:',
|
||||
],
|
||||
'out_excludes': [
|
||||
'flavor-list',
|
||||
'--os-username OS_USERNAME',
|
||||
'Display help for <subcommand>',
|
||||
'--capacities CAPACITIES',
|
||||
],
|
||||
'err_string': '',
|
||||
'return_code': 0,
|
||||
},
|
||||
{
|
||||
'commands': ['flavor-update -h',
|
||||
'flavor-update --help',
|
||||
'help flavor-update'],
|
||||
'test_identifiers': ['test_flavor_update_dash_h',
|
||||
'test_flavor_update_dashdash_help',
|
||||
'test_help_flavor_update'],
|
||||
'out_includes': [
|
||||
'usage: tuskar flavor-update [-h] [--name NAME]'
|
||||
+ ' [--capacities CAPACITIES]',
|
||||
'positional arguments:',
|
||||
'optional arguments:',
|
||||
'--capacities CAPACITIES',
|
||||
'--name NAME',
|
||||
'--max-vms MAX_VMS',
|
||||
],
|
||||
'out_excludes': [
|
||||
'flavor-list',
|
||||
'--os-username OS_USERNAME',
|
||||
'Display help for <subcommand>',
|
||||
],
|
||||
'err_string': '',
|
||||
'return_code': 0,
|
||||
},
|
||||
{
|
||||
'commands': ['flavor-create -h',
|
||||
'flavor-create --help',
|
||||
'help flavor-create'],
|
||||
'test_identifiers': ['test_flavor_create_dash_h',
|
||||
'test_flavor_create_dashdash_help',
|
||||
'test_help_flavor_create'],
|
||||
'out_includes': [
|
||||
'usage:',
|
||||
'positional arguments:',
|
||||
'optional arguments:',
|
||||
'--capacities CAPACITIES',
|
||||
],
|
||||
'out_excludes': [
|
||||
'flavor-list',
|
||||
'--os-username OS_USERNAME',
|
||||
'Display help for <subcommand>',
|
||||
],
|
||||
'err_string': '',
|
||||
'return_code': 0,
|
||||
},
|
||||
{
|
||||
'commands': ['flavor-show -h',
|
||||
'flavor-show --help',
|
||||
'help flavor-show'],
|
||||
'test_identifiers': ['test_flavor_show_dash_h',
|
||||
'test_flavor_show_dashdash_help',
|
||||
'test_help_flavor_show'],
|
||||
'out_includes': [
|
||||
'usage: tuskar flavor-show [-h] <RESOURCE CLASS NAME or ID>'
|
||||
+ ' <FLAVOR NAME or ID>',
|
||||
'positional arguments:',
|
||||
'optional arguments:',
|
||||
'Name or ID of resource class associated to.',
|
||||
],
|
||||
'out_excludes': [
|
||||
'flavor-list',
|
||||
'--os-username OS_USERNAME',
|
||||
'Display help for <subcommand>',
|
||||
'--capacities CAPACITIES',
|
||||
],
|
||||
'err_string': '',
|
||||
'return_code': 0,
|
||||
},
|
||||
{
|
||||
'commands': ['flavor-list -h',
|
||||
'flavor-list --help',
|
||||
'help flavor-list'],
|
||||
'test_identifiers': ['test_flavor_list_dash_h',
|
||||
'test_flavor_list_dashdash_help',
|
||||
'test_help_flavor_list'],
|
||||
'out_includes': [
|
||||
'usage: tuskar flavor-list [-h] <RESOURCE CLASS NAME or ID>',
|
||||
'positional arguments:',
|
||||
'optional arguments:',
|
||||
],
|
||||
'out_excludes': [
|
||||
'--os-username OS_USERNAME',
|
||||
'Display help for <subcommand>',
|
||||
'--capacities CAPACITIES',
|
||||
],
|
||||
'err_string': '',
|
||||
'return_code': 0,
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
def create_test_method(command, expected_values):
|
||||
def test_command_method(self):
|
||||
self.assertThat(
|
||||
self.run_tuskar(command),
|
||||
tutils.CommandOutputMatches(
|
||||
out_str=expected_values.get('out_string'),
|
||||
out_inc=expected_values.get('out_includes'),
|
||||
out_exc=expected_values.get('out_excludes'),
|
||||
err_str=expected_values.get('err_string'),
|
||||
err_inc=expected_values.get('err_includes'),
|
||||
err_exc=expected_values.get('err_excludes'),
|
||||
))
|
||||
return test_command_method
|
||||
|
||||
# creates a method for each command found in tests
|
||||
# to let developer see what test is failing in test results,
|
||||
# ie: ... HelpCommandTest.test_help_flavor_list
|
||||
# this way dev can "just search" for "test_help_flavor_list"
|
||||
# and he will find actual data used in failing test
|
||||
for test in tests:
|
||||
commands = test.get('commands')
|
||||
for index, command in enumerate(commands):
|
||||
test_command_method = create_test_method(command, test)
|
||||
test_command_method.__name__ = test.get('test_identifiers')[index]
|
||||
setattr(HelpCommandTest,
|
||||
test_command_method.__name__,
|
||||
test_command_method)
|
@ -24,7 +24,7 @@ class ShellTest(tutils.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(ShellTest, self).setUp()
|
||||
self.s = shell.TuskarShell({})
|
||||
self.s = shell.TuskarShell([])
|
||||
|
||||
def empty_args(self):
|
||||
args = lambda: None # i'd use object(), but it can't have attributes
|
||||
@ -61,7 +61,7 @@ class ShellTest(tutils.TestCase):
|
||||
v1_commands = [
|
||||
'rack-list', 'rack-show',
|
||||
]
|
||||
parser = self.s._parser(1)
|
||||
parser, subparsers = self.s._parser(1)
|
||||
tuskar_help = parser.format_help()
|
||||
|
||||
for arg in map(lambda a: a.replace('_', '-'), self.args_attributes):
|
||||
|
@ -10,14 +10,18 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import argparse
|
||||
import copy
|
||||
import fixtures
|
||||
from gettext import gettext as _
|
||||
import os
|
||||
import sys
|
||||
|
||||
from six import StringIO
|
||||
import testtools
|
||||
|
||||
from tuskarclient.common import http
|
||||
from tuskarclient import shell
|
||||
|
||||
|
||||
class TestCase(testtools.TestCase):
|
||||
@ -34,6 +38,196 @@ class TestCase(testtools.TestCase):
|
||||
self.useFixture(fixtures.MonkeyPatch('sys.stderr', stderr))
|
||||
|
||||
|
||||
class CommandTestCase(TestCase):
|
||||
def setUp(self):
|
||||
super(CommandTestCase, self).setUp()
|
||||
self.tuskar_bin = os.path.join(
|
||||
os.path.dirname(os.path.realpath(sys.executable)),
|
||||
'tuskar')
|
||||
|
||||
def run_tuskar(self, params=''):
|
||||
args = params.split()
|
||||
out = StringIO()
|
||||
err = StringIO()
|
||||
ArgumentParserForTests.OUT = out
|
||||
ArgumentParserForTests.ERR = err
|
||||
try:
|
||||
shell.TuskarShell(
|
||||
args, argument_parser_class=ArgumentParserForTests).run()
|
||||
except TestExit:
|
||||
pass
|
||||
outvalue = out.getvalue()
|
||||
errvalue = err.getvalue()
|
||||
return [outvalue, errvalue]
|
||||
|
||||
|
||||
class CommandOutputMatches(object):
|
||||
def __init__(self,
|
||||
out_str=None, out_inc=None, out_exc=None,
|
||||
err_str=None, err_inc=None, err_exc=None,
|
||||
return_code=None):
|
||||
self.out_str = out_str
|
||||
self.out_inc = out_inc or []
|
||||
self.out_exc = out_exc or []
|
||||
self.err_str = err_str
|
||||
self.err_inc = err_inc or []
|
||||
self.err_exc = err_exc or []
|
||||
self.return_code = return_code
|
||||
|
||||
def match(self, outputs):
|
||||
out, err = outputs[0], outputs[1]
|
||||
errors = []
|
||||
|
||||
# tests for exact output and error output match
|
||||
errors.append(self.match_output(out, self.out_str, type='output'))
|
||||
errors.append(self.match_output(err, self.err_str, type='error'))
|
||||
|
||||
# tests for what output should include and what it should not
|
||||
errors.append(self.match_includes(out, self.out_inc, type='output'))
|
||||
errors.append(self.match_excludes(out, self.out_exc, type='output'))
|
||||
|
||||
# tests for what error output should include and what it should not
|
||||
errors.append(self.match_includes(err, self.err_inc, type='error'))
|
||||
errors.append(self.match_excludes(err, self.err_exc, type='error'))
|
||||
|
||||
# get first non None item or None if none is found and return it
|
||||
return next((item for item in errors if item is not None), None)
|
||||
|
||||
def match_return_code(self, return_code, expected_return_code):
|
||||
if expected_return_code is not None:
|
||||
if expected_return_code != return_code:
|
||||
return CommandOutputReturnCodeMismatch(
|
||||
return_code, expected_return_code)
|
||||
|
||||
def match_output(self, output, expected_output, type='output'):
|
||||
if expected_output is not None:
|
||||
if expected_output != output:
|
||||
return CommandOutputMismatch(
|
||||
output, expected_output, type=type)
|
||||
|
||||
def match_includes(self, output, includes, type='output'):
|
||||
for part in includes:
|
||||
if part not in output:
|
||||
return CommandOutputMissingMismatch(output, part, type=type)
|
||||
|
||||
def match_excludes(self, output, excludes, type='error'):
|
||||
for part in excludes:
|
||||
if part in output:
|
||||
return CommandOutputExtraMismatch(output, part, type=type)
|
||||
|
||||
|
||||
class CommandOutputMismatch(object):
|
||||
def __init__(self, out, out_str, type='output'):
|
||||
if type == 'error':
|
||||
self.type = 'Error output'
|
||||
else:
|
||||
self.type = 'Output'
|
||||
self.out = out
|
||||
self.out_str = out_str
|
||||
|
||||
def describe(self):
|
||||
return "%s '%s' should be '%s'" % (self.type, self.out, self.out_str)
|
||||
|
||||
def get_details(self):
|
||||
return {}
|
||||
|
||||
|
||||
class CommandOutputMissingMismatch(object):
|
||||
def __init__(self, out, out_inc, type='output'):
|
||||
if type == 'error':
|
||||
self.type = 'Error output'
|
||||
else:
|
||||
self.type = 'Output'
|
||||
self.out = out
|
||||
self.out_inc = out_inc
|
||||
|
||||
def describe(self):
|
||||
return "%s '%s' should contain '%s'"\
|
||||
% (self.type, self.out, self.out_inc)
|
||||
|
||||
def get_details(self):
|
||||
return {}
|
||||
|
||||
|
||||
class CommandOutputExtraMismatch(object):
|
||||
def __init__(self, out, out_exc, type='output'):
|
||||
if type == 'error':
|
||||
self.type = 'Error output'
|
||||
else:
|
||||
self.type = 'Output'
|
||||
self.out = out
|
||||
self.out_exc = out_exc
|
||||
|
||||
def describe(self):
|
||||
return "%s '%s' should not contain '%s'"\
|
||||
% (self.type, self.out, self.out_exc)
|
||||
|
||||
def get_details(self):
|
||||
return {}
|
||||
|
||||
|
||||
class CommandOutputReturnCodeMismatch(object):
|
||||
def __init__(self, ret, ret_exp):
|
||||
self.ret = ret
|
||||
self.ret_exp = ret_exp
|
||||
|
||||
def describe(self):
|
||||
return "Return code is '%s' but expected '%s'"\
|
||||
% (self.ret, self.ret_exp)
|
||||
|
||||
def get_details(self):
|
||||
return {}
|
||||
|
||||
|
||||
class TestExit(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class ArgumentParserForTests(argparse.ArgumentParser):
|
||||
OUT = sys.stdout
|
||||
ERR = sys.stderr
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self.out = ArgumentParserForTests.OUT
|
||||
self.err = ArgumentParserForTests.ERR
|
||||
|
||||
super(ArgumentParserForTests, self).__init__(**kwargs)
|
||||
|
||||
def error(self, message):
|
||||
self.print_usage(self.err)
|
||||
self.exit(2, _('%(prog)s: error: %(message)s\n') %
|
||||
{'prog': self.prog, 'message': message})
|
||||
|
||||
def exit(self, status=0, message=None):
|
||||
if message:
|
||||
self._print_message(message, self.err)
|
||||
raise TestExit
|
||||
|
||||
def print_usage(self, file=None):
|
||||
if file is None:
|
||||
file = self.out
|
||||
self._print_message(self.format_usage(), file)
|
||||
|
||||
def print_help(self, file=None):
|
||||
if file is None:
|
||||
file = self.out
|
||||
self._print_message(self.format_help(), file)
|
||||
|
||||
def print_version(self, file=None):
|
||||
import warnings
|
||||
warnings.warn(
|
||||
'The print_version method is deprecated -- the "version" '
|
||||
'argument to ArgumentParser is no longer supported.',
|
||||
DeprecationWarning)
|
||||
self._print_message(self.format_version(), file)
|
||||
|
||||
def _print_message(self, message, file=None):
|
||||
if message:
|
||||
if file is None:
|
||||
file = self.err
|
||||
file.write(message)
|
||||
|
||||
|
||||
class FakeAPI(object):
|
||||
def __init__(self, fixtures):
|
||||
self.fixtures = fixtures
|
||||
|
Loading…
Reference in New Issue
Block a user