def action(self, command):
        """
        Add a subcommand. (Alias `subcommand`).

        :param command: a function or a Command

        You can add a :class:`Command` as an action, or a function::

            command.action(subcommand)

        If you prefer a decorator::

            @command.action
            def server(port=5000):
                '''
                docstring as the description

                :param port: description of port
                '''
                start_server(port)

        It will auto generate a subcommand from the ``server`` method.
        """

        if isinstance(command, Command):
            self._command_list.append(command)
            return command

        # it is a function
        func = command
        args, varargs, keywords, defaults = inspect.getargspec(func)

        if func.__doc__:
            doclines = func.__doc__.splitlines()
        else:
            doclines = []
        doclines = filter(lambda o: o.strip(), doclines)
        doclines = list(map(lambda o: o.strip(), doclines))

        params = {}
        options = {}
        usage = None

        for line in doclines:
            if line.startswith('usage:'):
                usage = line[6:].strip()
            elif line.startswith(':param '):
                name, desc = line[7:].split(':', 1)
                params[name.strip()] = desc.strip()
            elif line.startswith(':option '):
                name, desc = line[8:].split(':', 1)
                options[name.strip()] = desc.strip()

        desc = None
        if doclines:
            desc = doclines[0]

        # use self.__class__ instead of Command for inherit
        cmd = self.__class__(func.__name__, desc, usage=usage)

        defaults = defaults or []
        kwargs = dict(zip(*[reversed(i) for i in (args, defaults)]))

        for arg in args:
            desc = params.get(arg, None)
            name = options.get(arg, None)
            if arg in kwargs:
                value = kwargs[arg]
                if value is True:
                    name = name or '--no-%s' % arg
                    option = Option(name, desc)
                elif value is False:
                    name = name or (arg[0], arg) % '-%s, --%s'
                    option = Option(name, desc)
                else:
                    name = name or '-%s, --%s [%s]' % (arg[0], arg, arg)
                    option = Option(name, desc)
                    option.default = value

                cmd.option(option)
            elif desc:
                # if has description, it is a required option
                name = name or '-%s, --%s <%s>' % (arg[0], arg, arg)
                cmd.option(name, desc)
            else:
                # positional arguments
                cmd._positional_list.append(arg)

        cmd._command_func = func
        self._command_list.append(cmd)
        return command
dataset/ETHPy150Open lepture/terminal/terminal/command.py/Command.action/swapped operands of `%`