Home | History | Annotate | Download | only in library
      1 :mod:`cmd` --- Support for line-oriented command interpreters
      2 =============================================================
      3 
      4 .. module:: cmd
      5    :synopsis: Build line-oriented command interpreters.
      6 
      7 .. sectionauthor:: Eric S. Raymond <esr (a] snark.thyrsus.com>
      8 
      9 **Source code:** :source:`Lib/cmd.py`
     10 
     11 --------------
     12 
     13 The :class:`Cmd` class provides a simple framework for writing line-oriented
     14 command interpreters.  These are often useful for test harnesses, administrative
     15 tools, and prototypes that will later be wrapped in a more sophisticated
     16 interface.
     17 
     18 .. class:: Cmd(completekey='tab', stdin=None, stdout=None)
     19 
     20    A :class:`Cmd` instance or subclass instance is a line-oriented interpreter
     21    framework.  There is no good reason to instantiate :class:`Cmd` itself; rather,
     22    it's useful as a superclass of an interpreter class you define yourself in order
     23    to inherit :class:`Cmd`'s methods and encapsulate action methods.
     24 
     25    The optional argument *completekey* is the :mod:`readline` name of a completion
     26    key; it defaults to :kbd:`Tab`. If *completekey* is not :const:`None` and
     27    :mod:`readline` is available, command completion is done automatically.
     28 
     29    The optional arguments *stdin* and *stdout* specify the  input and output file
     30    objects that the Cmd instance or subclass  instance will use for input and
     31    output. If not specified, they will default to :data:`sys.stdin` and
     32    :data:`sys.stdout`.
     33 
     34    If you want a given *stdin* to be used, make sure to set the instance's
     35    :attr:`use_rawinput` attribute to ``False``, otherwise *stdin* will be
     36    ignored.
     37 
     38 
     39 .. _cmd-objects:
     40 
     41 Cmd Objects
     42 -----------
     43 
     44 A :class:`Cmd` instance has the following methods:
     45 
     46 
     47 .. method:: Cmd.cmdloop(intro=None)
     48 
     49    Repeatedly issue a prompt, accept input, parse an initial prefix off the
     50    received input, and dispatch to action methods, passing them the remainder of
     51    the line as argument.
     52 
     53    The optional argument is a banner or intro string to be issued before the first
     54    prompt (this overrides the :attr:`intro` class attribute).
     55 
     56    If the :mod:`readline` module is loaded, input will automatically inherit
     57    :program:`bash`\ -like history-list editing (e.g. :kbd:`Control-P` scrolls back
     58    to the last command, :kbd:`Control-N` forward to the next one, :kbd:`Control-F`
     59    moves the cursor to the right non-destructively, :kbd:`Control-B` moves the
     60    cursor to the left non-destructively, etc.).
     61 
     62    An end-of-file on input is passed back as the string ``'EOF'``.
     63 
     64    .. index::
     65       single: ? (question mark); in a command interpreter
     66       single: ! (exclamation); in a command interpreter
     67 
     68    An interpreter instance will recognize a command name ``foo`` if and only if it
     69    has a method :meth:`do_foo`.  As a special case, a line beginning with the
     70    character ``'?'`` is dispatched to the method :meth:`do_help`.  As another
     71    special case, a line beginning with the character ``'!'`` is dispatched to the
     72    method :meth:`do_shell` (if such a method is defined).
     73 
     74    This method will return when the :meth:`postcmd` method returns a true value.
     75    The *stop* argument to :meth:`postcmd` is the return value from the command's
     76    corresponding :meth:`do_\*` method.
     77 
     78    If completion is enabled, completing commands will be done automatically, and
     79    completing of commands args is done by calling :meth:`complete_foo` with
     80    arguments *text*, *line*, *begidx*, and *endidx*.  *text* is the string prefix
     81    we are attempting to match: all returned matches must begin with it. *line* is
     82    the current input line with leading whitespace removed, *begidx* and *endidx*
     83    are the beginning and ending indexes of the prefix text, which could be used to
     84    provide different completion depending upon which position the argument is in.
     85 
     86    All subclasses of :class:`Cmd` inherit a predefined :meth:`do_help`.  This
     87    method, called with an argument ``'bar'``, invokes the corresponding method
     88    :meth:`help_bar`, and if that is not present, prints the docstring of
     89    :meth:`do_bar`, if available.  With no argument, :meth:`do_help` lists all
     90    available help topics (that is, all commands with corresponding
     91    :meth:`help_\*` methods or commands that have docstrings), and also lists any
     92    undocumented commands.
     93 
     94 
     95 .. method:: Cmd.onecmd(str)
     96 
     97    Interpret the argument as though it had been typed in response to the prompt.
     98    This may be overridden, but should not normally need to be; see the
     99    :meth:`precmd` and :meth:`postcmd` methods for useful execution hooks.  The
    100    return value is a flag indicating whether interpretation of commands by the
    101    interpreter should stop.  If there is a :meth:`do_\*` method for the command
    102    *str*, the return value of that method is returned, otherwise the return value
    103    from the :meth:`default` method is returned.
    104 
    105 
    106 .. method:: Cmd.emptyline()
    107 
    108    Method called when an empty line is entered in response to the prompt. If this
    109    method is not overridden, it repeats the last nonempty command entered.
    110 
    111 
    112 .. method:: Cmd.default(line)
    113 
    114    Method called on an input line when the command prefix is not recognized. If
    115    this method is not overridden, it prints an error message and returns.
    116 
    117 
    118 .. method:: Cmd.completedefault(text, line, begidx, endidx)
    119 
    120    Method called to complete an input line when no command-specific
    121    :meth:`complete_\*` method is available.  By default, it returns an empty list.
    122 
    123 
    124 .. method:: Cmd.precmd(line)
    125 
    126    Hook method executed just before the command line *line* is interpreted, but
    127    after the input prompt is generated and issued.  This method is a stub in
    128    :class:`Cmd`; it exists to be overridden by subclasses.  The return value is
    129    used as the command which will be executed by the :meth:`onecmd` method; the
    130    :meth:`precmd` implementation may re-write the command or simply return *line*
    131    unchanged.
    132 
    133 
    134 .. method:: Cmd.postcmd(stop, line)
    135 
    136    Hook method executed just after a command dispatch is finished.  This method is
    137    a stub in :class:`Cmd`; it exists to be overridden by subclasses.  *line* is the
    138    command line which was executed, and *stop* is a flag which indicates whether
    139    execution will be terminated after the call to :meth:`postcmd`; this will be the
    140    return value of the :meth:`onecmd` method.  The return value of this method will
    141    be used as the new value for the internal flag which corresponds to *stop*;
    142    returning false will cause interpretation to continue.
    143 
    144 
    145 .. method:: Cmd.preloop()
    146 
    147    Hook method executed once when :meth:`cmdloop` is called.  This method is a stub
    148    in :class:`Cmd`; it exists to be overridden by subclasses.
    149 
    150 
    151 .. method:: Cmd.postloop()
    152 
    153    Hook method executed once when :meth:`cmdloop` is about to return. This method
    154    is a stub in :class:`Cmd`; it exists to be overridden by subclasses.
    155 
    156 
    157 Instances of :class:`Cmd` subclasses have some public instance variables:
    158 
    159 .. attribute:: Cmd.prompt
    160 
    161    The prompt issued to solicit input.
    162 
    163 
    164 .. attribute:: Cmd.identchars
    165 
    166    The string of characters accepted for the command prefix.
    167 
    168 
    169 .. attribute:: Cmd.lastcmd
    170 
    171    The last nonempty command prefix seen.
    172 
    173 
    174 .. attribute:: Cmd.cmdqueue
    175 
    176    A list of queued input lines.  The cmdqueue list is checked in
    177    :meth:`cmdloop` when new input is needed; if it is nonempty, its elements
    178    will be processed in order, as if entered at the prompt.
    179 
    180 
    181 .. attribute:: Cmd.intro
    182 
    183    A string to issue as an intro or banner.  May be overridden by giving the
    184    :meth:`cmdloop` method an argument.
    185 
    186 
    187 .. attribute:: Cmd.doc_header
    188 
    189    The header to issue if the help output has a section for documented commands.
    190 
    191 
    192 .. attribute:: Cmd.misc_header
    193 
    194    The header to issue if the help output has a section for miscellaneous  help
    195    topics (that is, there are :meth:`help_\*` methods without corresponding
    196    :meth:`do_\*` methods).
    197 
    198 
    199 .. attribute:: Cmd.undoc_header
    200 
    201    The header to issue if the help output has a section for undocumented  commands
    202    (that is, there are :meth:`do_\*` methods without corresponding :meth:`help_\*`
    203    methods).
    204 
    205 
    206 .. attribute:: Cmd.ruler
    207 
    208    The character used to draw separator lines under the help-message headers.  If
    209    empty, no ruler line is drawn.  It defaults to ``'='``.
    210 
    211 
    212 .. attribute:: Cmd.use_rawinput
    213 
    214    A flag, defaulting to true.  If true, :meth:`cmdloop` uses :func:`input` to
    215    display a prompt and read the next command; if false, :meth:`sys.stdout.write`
    216    and :meth:`sys.stdin.readline` are used. (This means that by importing
    217    :mod:`readline`, on systems that support it, the interpreter will automatically
    218    support :program:`Emacs`\ -like line editing  and command-history keystrokes.)
    219 
    220 
    221 .. _cmd-example:
    222 
    223 Cmd Example
    224 -----------
    225 
    226 .. sectionauthor:: Raymond Hettinger <python at rcn dot com>
    227 
    228 The :mod:`cmd` module is mainly useful for building custom shells that let a
    229 user work with a program interactively.
    230 
    231 This section presents a simple example of how to build a shell around a few of
    232 the commands in the :mod:`turtle` module.
    233 
    234 Basic turtle commands such as :meth:`~turtle.forward` are added to a
    235 :class:`Cmd` subclass with method named :meth:`do_forward`.  The argument is
    236 converted to a number and dispatched to the turtle module.  The docstring is
    237 used in the help utility provided by the shell.
    238 
    239 The example also includes a basic record and playback facility implemented with
    240 the :meth:`~Cmd.precmd` method which is responsible for converting the input to
    241 lowercase and writing the commands to a file.  The :meth:`do_playback` method
    242 reads the file and adds the recorded commands to the :attr:`cmdqueue` for
    243 immediate playback::
    244 
    245     import cmd, sys
    246     from turtle import *
    247 
    248     class TurtleShell(cmd.Cmd):
    249         intro = 'Welcome to the turtle shell.   Type help or ? to list commands.\n'
    250         prompt = '(turtle) '
    251         file = None
    252 
    253         # ----- basic turtle commands -----
    254         def do_forward(self, arg):
    255             'Move the turtle forward by the specified distance:  FORWARD 10'
    256             forward(*parse(arg))
    257         def do_right(self, arg):
    258             'Turn turtle right by given number of degrees:  RIGHT 20'
    259             right(*parse(arg))
    260         def do_left(self, arg):
    261             'Turn turtle left by given number of degrees:  LEFT 90'
    262             left(*parse(arg))
    263         def do_goto(self, arg):
    264             'Move turtle to an absolute position with changing orientation.  GOTO 100 200'
    265             goto(*parse(arg))
    266         def do_home(self, arg):
    267             'Return turtle to the home position:  HOME'
    268             home()
    269         def do_circle(self, arg):
    270             'Draw circle with given radius an options extent and steps:  CIRCLE 50'
    271             circle(*parse(arg))
    272         def do_position(self, arg):
    273             'Print the current turtle position:  POSITION'
    274             print('Current position is %d %d\n' % position())
    275         def do_heading(self, arg):
    276             'Print the current turtle heading in degrees:  HEADING'
    277             print('Current heading is %d\n' % (heading(),))
    278         def do_color(self, arg):
    279             'Set the color:  COLOR BLUE'
    280             color(arg.lower())
    281         def do_undo(self, arg):
    282             'Undo (repeatedly) the last turtle action(s):  UNDO'
    283         def do_reset(self, arg):
    284             'Clear the screen and return turtle to center:  RESET'
    285             reset()
    286         def do_bye(self, arg):
    287             'Stop recording, close the turtle window, and exit:  BYE'
    288             print('Thank you for using Turtle')
    289             self.close()
    290             bye()
    291             return True
    292 
    293         # ----- record and playback -----
    294         def do_record(self, arg):
    295             'Save future commands to filename:  RECORD rose.cmd'
    296             self.file = open(arg, 'w')
    297         def do_playback(self, arg):
    298             'Playback commands from a file:  PLAYBACK rose.cmd'
    299             self.close()
    300             with open(arg) as f:
    301                 self.cmdqueue.extend(f.read().splitlines())
    302         def precmd(self, line):
    303             line = line.lower()
    304             if self.file and 'playback' not in line:
    305                 print(line, file=self.file)
    306             return line
    307         def close(self):
    308             if self.file:
    309                 self.file.close()
    310                 self.file = None
    311 
    312     def parse(arg):
    313         'Convert a series of zero or more numbers to an argument tuple'
    314         return tuple(map(int, arg.split()))
    315 
    316     if __name__ == '__main__':
    317         TurtleShell().cmdloop()
    318 
    319 
    320 Here is a sample session with the turtle shell showing the help functions, using
    321 blank lines to repeat commands, and the simple record and playback facility:
    322 
    323 .. code-block:: none
    324 
    325     Welcome to the turtle shell.   Type help or ? to list commands.
    326 
    327     (turtle) ?
    328 
    329     Documented commands (type help <topic>):
    330     ========================================
    331     bye     color    goto     home  playback  record  right
    332     circle  forward  heading  left  position  reset   undo
    333 
    334     (turtle) help forward
    335     Move the turtle forward by the specified distance:  FORWARD 10
    336     (turtle) record spiral.cmd
    337     (turtle) position
    338     Current position is 0 0
    339 
    340     (turtle) heading
    341     Current heading is 0
    342 
    343     (turtle) reset
    344     (turtle) circle 20
    345     (turtle) right 30
    346     (turtle) circle 40
    347     (turtle) right 30
    348     (turtle) circle 60
    349     (turtle) right 30
    350     (turtle) circle 80
    351     (turtle) right 30
    352     (turtle) circle 100
    353     (turtle) right 30
    354     (turtle) circle 120
    355     (turtle) right 30
    356     (turtle) circle 120
    357     (turtle) heading
    358     Current heading is 180
    359 
    360     (turtle) forward 100
    361     (turtle)
    362     (turtle) right 90
    363     (turtle) forward 100
    364     (turtle)
    365     (turtle) right 90
    366     (turtle) forward 400
    367     (turtle) right 90
    368     (turtle) forward 500
    369     (turtle) right 90
    370     (turtle) forward 400
    371     (turtle) right 90
    372     (turtle) forward 300
    373     (turtle) playback spiral.cmd
    374     Current position is 0 0
    375 
    376     Current heading is 0
    377 
    378     Current heading is 180
    379 
    380     (turtle) bye
    381     Thank you for using Turtle
    382