def create_subparser_class()

in nubia/internal/typing/argparse.py [0:0]


def create_subparser_class(opts_parser):
    # This is a hack to add the main parser arguments to each subcommand in
    # order to allow main parser arguments to be specified after the
    # subcommand, e.g.
    #    my_prog status -t <tier> --atonce=10
    #
    # The rationale of the implementation chosen is to propagate mutually
    # exclusive groups from main parser to subparsers. While it is  possible
    # to infer kwargs from main parser actions list then passing them to the
    # add_argument() method for each subparser, it will make us lose any
    # information about mutually exclusive groups.

    class SubParser(argparse.ArgumentParser):
        def __init__(self, *args, **kwargs):
            kwargs["add_help"] = False
            super(SubParser, self).__init__(*args, **kwargs)
            self._copied_actions_fingerprints = set()
            # Copy mutually exclusive groups first
            self._copy_mutually_exclusive_groups()
            # Obviously we care only about optionals
            self._copy_optionals()

        def _copy_action(self, action, group, default=argparse.SUPPRESS):
            action_fingerprint = "".join(action.option_strings)
            # Avoid adding same option twice
            if action_fingerprint not in self._copied_actions_fingerprints:
                # FIXME: this is a really, really bad idea
                a = copy.copy(action)
                # Avoid common arguments to be overridden by subnamespace
                a.default = default
                group._add_action(a)
                self._copied_actions_fingerprints.add(action_fingerprint)

        def _copy_mutually_exclusive_groups(self):
            for mutex_group in opts_parser._mutually_exclusive_groups:
                mutex_group_copy = self.add_mutually_exclusive_group(
                    required=mutex_group.required
                )

                for action in mutex_group._group_actions:
                    self._copy_action(action, mutex_group_copy)

        def _copy_optionals(self):
            for action in opts_parser._optionals._actions:
                # Skip _SubParsersAction from main parser
                if not isinstance(action, argparse._SubParsersAction):
                    self._copy_action(action, self._optionals)

    return SubParser