[Python-Dev] New Module: CommandLoop

Crutcher Dunnavant crutcher at gmail.com
Mon Feb 20 01:26:25 CET 2006

Whoa, thanks. Incorporated the suggestions to the code.

On 2/19/06, Raymond Hettinger <python at rcn.com> wrote:
> [Crutcher Dunnavant]
> > Anyway, I'm looking for feedback, feature requests before starting the
> > submission process.
> With respect to the API, the examples tend to be visually dominated dominated by
> the series of decorators.  The three decorators do nothing more than add a
> function attribute, so they are essentially doing the same type of action.
> Consider combining those into a single decorator and using keywords for the
> various arguments.  For example, change:
>         @cmdloop.aliases('goodbye')
>         @cmdloop.shorthelp('say goodbye')
>         @cmdloop.usage('goodbye TARGET')
> to just:
>         @cmdloop.addspec(aliases=['goodbye'], shorthelp ='say goodbye',
> usage='goodbye TARGET')
> leaving the possibility of multiple decorators when one line gets to long:
>         @cmdloop.addspec(aliases=['goodbye'], shorthelp ='say goodbye')
>         @cmdloop.addspec(usage='goodbye TARGET  # where TARGET is a filename in
> the current directory')

Well, why not support both, and leave it up to the user?

> Another thought on the API is to consider adding another decorator option to
> make commands case-insensitive so that 'help', 'HELP', and 'Help' will all work:
>          @cmdloop.addspec(case_sensitive=True)

shouldn't this be a property of the shell, and not the individual commands?
Perhaps a CASE_SENSITIVE=False attribute on the shell?

> Also, in the absence of readline(), consider adding support for "!" style
> repeats of previous commands.

How would this work? Would it be a simple replay of the previous
command? Would it search a command history? How do we make it interact
with the _preCommand code? I'm not sure how to make this work.

> The exception hierarchy looks to be well-designed.  I'm not clear on whether it
> is internal or part of the API.  If the latter, is there an example of how to
> trap and handle specific exceptions in specific contexts?

The exceptions are part of the API, but are only meant to be thrown by
user code, and handled by the module code. There aren't any situations
when user code needs to catch modules that I know of.

> If you're interested, here are a few code comments based on my first
> read-through:
> 1) The "chars" variable can be eliminated and the "while chars" and
> "c=chars.pop(0)" sequence simplified to just:
>     for c in reversed(str):
>         . . .

chars is something of a navel. The parser went through some evolution,
and for a time, it _didn't_ consume a character every time arround.
However, the chars are not reversed, so given s/str/cmdline/g:

for c in cmdline:

> 2) Can the reformatDocString() function be replaced by textwrap.dedent() or do
> they do something different?

I guess so, they seem to do the same thing.

> 3) In _mapCommands(), the sort can be simplified from:
>         self._cmds.sort(lambda a, b: cmp(a.aliases[0], b.aliases[0]))
>     to:
>         self._cmds.sort(key=operator.itemgetter(0))
>     or if you want to avoid module dependencies:
>         self._cmds.sort(key=lambda a: a[0])

well, almost. we are sorting on the aliases, so
self._cmds.sort(key=lambda a: a.aliases[0])

> 4) In _preCommand, the sort simplifies from:
>                     names = self.aliasdict.keys()
>                     names.sort()
>                     for name in names:
>     to:
>                     for name in sorted(self.aliasdict):


> Raymond

Crutcher Dunnavant <crutcher at gmail.com>

More information about the Python-Dev mailing list