diff --git a/awxkit/awxkit/cli/client.py b/awxkit/awxkit/cli/client.py index de68801af5..bcd97fe701 100755 --- a/awxkit/awxkit/cli/client.py +++ b/awxkit/awxkit/cli/client.py @@ -170,9 +170,9 @@ class CLI(object): if formatted: print(utils.to_str(formatted), file=self.stdout) else: - self.parser.print_help() - - if six.PY2 and not self.help: + if six.PY3: + self.parser.print_help() + elif six.PY2 and not self.help: # Unfortunately, argparse behavior between py2 and py3 # changed in a notable way when required subparsers # have invalid (or missing) arguments specified diff --git a/awxkit/awxkit/cli/resource.py b/awxkit/awxkit/cli/resource.py index be4f7409fb..df1d4d5f21 100644 --- a/awxkit/awxkit/cli/resource.py +++ b/awxkit/awxkit/cli/resource.py @@ -137,9 +137,10 @@ def parse_resource(client, skip_deprecated=False): # argparse aliases are *only* supported in Python3 (not 2.7) kwargs = {} - if not skip_deprecated and PY3: + if not skip_deprecated: if k in DEPRECATED_RESOURCES: kwargs['aliases'] = [DEPRECATED_RESOURCES[k]] + client.subparsers[k] = subparsers.add_parser( k, help='', **kwargs ) diff --git a/awxkit/awxkit/cli/utils.py b/awxkit/awxkit/cli/utils.py index 3048ef6a6a..188010ecc5 100644 --- a/awxkit/awxkit/cli/utils.py +++ b/awxkit/awxkit/cli/utils.py @@ -5,6 +5,8 @@ import os import sys import threading +import six + _color = threading.local() _color.enabled = True @@ -36,6 +38,29 @@ class CustomRegistryMeta(type): class HelpfulArgumentParser(ArgumentParser): + def __init__(self, *args, **kwargs): + super(HelpfulArgumentParser, self).__init__(*args, **kwargs) + if six.PY2: + # backport parser aliases support to py2 + # see: https://github.com/python/cpython/commit/fd311a712d5876c3a3efff265978452eea759f85 + SubParsersAction = self._registries['action']['parsers'] + + class _SubParsersAction(SubParsersAction): + + def add_parser(self, name, **kwargs): + aliases = kwargs.pop('aliases', []) + parser = super(_SubParsersAction, self).add_parser(name, **kwargs) + if aliases: + self._choices_actions[-1].metavar = ' '.join([ + name, + '({})'.format(', '.join(aliases)) + ]) + for alias in aliases: + self._name_parser_map[alias] = parser + return parser + + self._registries['action']['parsers'] = _SubParsersAction + def error(self, message): # pragma: nocover """Prints a usage message incorporating the message to stderr and exits.