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@snark.thyrsus.com> 8 9**Source code:** :source:`Lib/cmd.py` 10 11-------------- 12 13The :class:`Cmd` class provides a simple framework for writing line-oriented 14command interpreters. These are often useful for test harnesses, administrative 15tools, and prototypes that will later be wrapped in a more sophisticated 16interface. 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 41Cmd Objects 42----------- 43 44A :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 157Instances 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 223Cmd Example 224----------- 225 226.. sectionauthor:: Raymond Hettinger <python at rcn dot com> 227 228The :mod:`cmd` module is mainly useful for building custom shells that let a 229user work with a program interactively. 230 231This section presents a simple example of how to build a shell around a few of 232the commands in the :mod:`turtle` module. 233 234Basic turtle commands such as :meth:`~turtle.forward` are added to a 235:class:`Cmd` subclass with method named :meth:`do_forward`. The argument is 236converted to a number and dispatched to the turtle module. The docstring is 237used in the help utility provided by the shell. 238 239The example also includes a basic record and playback facility implemented with 240the :meth:`~Cmd.precmd` method which is responsible for converting the input to 241lowercase and writing the commands to a file. The :meth:`do_playback` method 242reads the file and adds the recorded commands to the :attr:`cmdqueue` for 243immediate 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 320Here is a sample session with the turtle shell showing the help functions, using 321blank 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