A question about Cmd Class

Peter Otten __peter__ at web.de
Tue Mar 8 08:09:01 EST 2011


yuan zheng wrote:

> Hello, everyone:
> 
>     I encouter a question when implementing a commmand line(shell).
> I have implemented some commands, such as "start", "stop", "quit",
> they are easily implemented by "do_start", "do_stop" and "do_quit".
> there are no troubles.
>      But I want to implement some commands like these "list-modules",
> "show-info". There is a character "-" among the string. So I can't easily
> use "do_list-modules", because the name is invalid. I attempt another
> ways, add a sentense in function "cmd.onecmd":
> -------------------------------------------------------
>    def onecmd(self, line):
>         line = line.replace("-", "_")         # I add
>     ...
> -------------------------------------------------------
> Then, I can use "do_list_modules" to mach "list-modules" command. But in
> this way, completion cannot work correctly. If I input "list-", and then
> "tab",
> it would not complete.
> 
> If my way is correct when encoutering commands with "-" ?
> If it's correct, how can I implement completion to work correctly?

It looks like the command class hasn't been designed with that kind of 
flexibility in mind. Here's how far I got:

import cmd

class MyCmd(cmd.Cmd):
    identchars = cmd.Cmd.identchars + "-"
    def get_names(self):
        names = cmd.Cmd.get_names(self)
        result = []
        for name in names:
            if name.startswith("do_"):
                name = "do_" + name[3:].replace("_", "-")
            result.append(name)
        return result

    def __getattr__(self, name):
        if "-" in name:
            return getattr(self, name.replace("-", "_"))
        raise AttributeError

    def completenames(self, text, *ignored):
        return cmd.Cmd.completenames(self, text.replace("-", "_"), *ignored)

class Cmd(MyCmd):
    def do_eat_fish(self, rest):
        print "eat fish", rest
    def do_drink_beer(self, rest):
        print "drink beer", rest
    def do_EOF(self, rest):
        return True

if __name__ == "__main__":
    c = Cmd()
    c.cmdloop()

If you need the "help_" prefix to work, too, you have to tweak it further.
I don't know if there are other hidden quirks...

Peter




More information about the Python-list mailing list