Esempio n. 1
0
def _wrap_stout_cmd_doc(indent, doc, max_width):
    """Function for wrapping command description."""
    parts = []
    paras = [
        '\n'.join(para)
        for para in split(doc.splitlines(), lambda l: not l.lstrip()) if para
    ]
    for para in paras:
        part = textwrap.fill(text=para,
                             width=(max_width - len(indent)),
                             initial_indent=indent,
                             subsequent_indent=indent)
        parts.append(part)
    return '\n\n'.join(parts)
Esempio n. 2
0
    def parse(self, argv):
        """This method takes a list of strings and converts them into a
        validated :class:`CommandParseResult` according to the flags,
        subparsers, and other options configured.

        Args:
           argv (list): A required list of strings. Pass ``None`` to
              use ``sys.argv``.

        This method may raise ArgumentParseError (or one of its
        subtypes) if the list of strings fails to parse.

        .. note:: The *argv* parameter does not automatically default
                  to using ``sys.argv`` because it's best practice for
                  implementing codebases to perform that sort of
                  defaulting in their ``main()``, which should accept
                  an ``argv=None`` parameter. This simple step ensures
                  that the Python CLI application has some sort of
                  programmatic interface that doesn't require
                  subprocessing. See here for an example.

        """
        if argv is None:
            argv = sys.argv
        if not argv:
            raise ArgumentParseError(
                'expected non-empty sequence of arguments, not: %r' % (argv, ))

        flag_map = None
        # first snip off the first argument, the command itself
        cmd_name, args = argv[0], list(argv)[1:]

        # we record our progress as we parse to provide the most
        # up-to-date info possible to the error and help handlers
        cpr = CommandParseResult(cmd_name, parser=self, argv=argv)

        try:
            # then figure out the subcommand path
            subcmds, args = self._parse_subcmds(args)
            cpr.subcmds = tuple(subcmds)

            prs = self.subprs_map[tuple(subcmds)] if subcmds else self

            # then look up the subcommand's supported flags
            # NOTE: get_flag_map() is used so that inheritors, like Command,
            # can filter by actually-used arguments, not just
            # available arguments.
            cmd_flag_map = self.get_flag_map(path=tuple(subcmds))

            # parse supported flags and validate their arguments
            flag_map, flagfile_map, posargs = self._parse_flags(
                cmd_flag_map, args)
            cpr.flags = OrderedDict(flag_map)
            cpr.posargs = tuple(posargs)

            # take care of dupes and check required flags
            resolved_flag_map = self._resolve_flags(cmd_flag_map, flag_map,
                                                    flagfile_map)
            cpr.flags = OrderedDict(resolved_flag_map)

            # separate out any trailing arguments from normal positional arguments
            post_posargs = None  # TODO: default to empty list?
            parsed_post_posargs = None
            if '--' in posargs:
                posargs, post_posargs = split(posargs, '--', 1)
                cpr.posargs, cpr.post_posargs = posargs, post_posargs

                parsed_post_posargs = prs.post_posargs.parse(post_posargs)
                cpr.post_posargs = tuple(parsed_post_posargs)

            parsed_posargs = prs.posargs.parse(posargs)
            cpr.posargs = tuple(parsed_posargs)
        except ArgumentParseError as ape:
            ape.prs_res = cpr
            raise

        return cpr