@@ -45,6 +45,24 @@ interface.
4545 .. versionchanged :: 3.13
4646 ``completekey='tab' `` is replaced by ``'^I' `` for ``editline ``.
4747
48+ .. note ::
49+
50+ Subtle behaviors of ``cmd.Cmd ``:
51+
52+ * Command handler methods (``do_<command> ``) should return ``True `` to
53+ indicate that the command loop should terminate. Any other return
54+ value continues the loop.
55+
56+ * If the user presses Enter on an empty line, the default behavior is
57+ to repeat the last nonempty command entered. This can be disabled by
58+ overriding :meth: `emptyline `.
59+
60+ * If no matching ``do_<command> `` method is found, the
61+ :meth: `default ` method is called.
62+
63+ * Exceptions raised inside command handlers are not caught by default
64+ and will terminate the command loop unless handled explicitly.
65+
4866
4967.. _cmd-objects :
5068
@@ -92,310 +110,3 @@ A :class:`Cmd` instance has the following methods:
92110 the current input line with leading whitespace removed, *begidx * and *endidx *
93111 are the beginning and ending indexes of the prefix text, which could be used to
94112 provide different completion depending upon which position the argument is in.
95-
96-
97- .. method :: Cmd.do_help(arg)
98-
99- All subclasses of :class: `Cmd ` inherit a predefined :meth: `!do_help `. This
100- method, called with an argument ``'bar' ``, invokes the corresponding method
101- :meth: `!help_bar `, and if that is not present, prints the docstring of
102- :meth: `!do_bar `, if available. With no argument, :meth: `!do_help ` lists all
103- available help topics (that is, all commands with corresponding
104- :meth: `!help_\* ` methods or commands that have docstrings), and also lists any
105- undocumented commands.
106-
107-
108- .. method :: Cmd.onecmd(str)
109-
110- Interpret the argument as though it had been typed in response to the prompt.
111- This may be overridden, but should not normally need to be; see the
112- :meth: `precmd ` and :meth: `postcmd ` methods for useful execution hooks. The
113- return value is a flag indicating whether interpretation of commands by the
114- interpreter should stop. If there is a :meth: `!do_\* ` method for the command
115- *str *, the return value of that method is returned, otherwise the return value
116- from the :meth: `default ` method is returned.
117-
118-
119- .. method :: Cmd.emptyline()
120-
121- Method called when an empty line is entered in response to the prompt. If this
122- method is not overridden, it repeats the last nonempty command entered.
123-
124-
125- .. method :: Cmd.default(line)
126-
127- Method called on an input line when the command prefix is not recognized. If
128- this method is not overridden, it prints an error message and returns.
129-
130-
131- .. method :: Cmd.completedefault(text, line, begidx, endidx)
132-
133- Method called to complete an input line when no command-specific
134- :meth: `!complete_\* ` method is available. By default, it returns an empty list.
135-
136-
137- .. method :: Cmd.columnize(list, displaywidth=80)
138-
139- Method called to display a list of strings as a compact set of columns.
140- Each column is only as wide as necessary.
141- Columns are separated by two spaces for readability.
142-
143-
144- .. method :: Cmd.precmd(line)
145-
146- Hook method executed just before the command line *line * is interpreted, but
147- after the input prompt is generated and issued. This method is a stub in
148- :class: `Cmd `; it exists to be overridden by subclasses. The return value is
149- used as the command which will be executed by the :meth: `onecmd ` method; the
150- :meth: `precmd ` implementation may re-write the command or simply return *line *
151- unchanged.
152-
153-
154- .. method :: Cmd.postcmd(stop, line)
155-
156- Hook method executed just after a command dispatch is finished. This method is
157- a stub in :class: `Cmd `; it exists to be overridden by subclasses. *line * is the
158- command line which was executed, and *stop * is a flag which indicates whether
159- execution will be terminated after the call to :meth: `postcmd `; this will be the
160- return value of the :meth: `onecmd ` method. The return value of this method will
161- be used as the new value for the internal flag which corresponds to *stop *;
162- returning false will cause interpretation to continue.
163-
164-
165- .. method :: Cmd.preloop()
166-
167- Hook method executed once when :meth: `cmdloop ` is called. This method is a stub
168- in :class: `Cmd `; it exists to be overridden by subclasses.
169-
170-
171- .. method :: Cmd.postloop()
172-
173- Hook method executed once when :meth: `cmdloop ` is about to return. This method
174- is a stub in :class: `Cmd `; it exists to be overridden by subclasses.
175-
176-
177- Instances of :class: `Cmd ` subclasses have some public instance variables:
178-
179- .. attribute :: Cmd.prompt
180-
181- The prompt issued to solicit input.
182-
183-
184- .. attribute :: Cmd.identchars
185-
186- The string of characters accepted for the command prefix.
187-
188-
189- .. attribute :: Cmd.lastcmd
190-
191- The last nonempty command prefix seen.
192-
193-
194- .. attribute :: Cmd.cmdqueue
195-
196- A list of queued input lines. The cmdqueue list is checked in
197- :meth: `cmdloop ` when new input is needed; if it is nonempty, its elements
198- will be processed in order, as if entered at the prompt.
199-
200-
201- .. attribute :: Cmd.intro
202-
203- A string to issue as an intro or banner. May be overridden by giving the
204- :meth: `cmdloop ` method an argument.
205-
206-
207- .. attribute :: Cmd.doc_header
208-
209- The header to issue if the help output has a section for documented commands.
210-
211-
212- .. attribute :: Cmd.misc_header
213-
214- The header to issue if the help output has a section for miscellaneous help
215- topics (that is, there are :meth: `!help_\* ` methods without corresponding
216- :meth: `!do_\* ` methods).
217-
218-
219- .. attribute :: Cmd.undoc_header
220-
221- The header to issue if the help output has a section for undocumented commands
222- (that is, there are :meth: `!do_\* ` methods without corresponding :meth: `!help_\* `
223- methods).
224-
225-
226- .. attribute :: Cmd.ruler
227-
228- The character used to draw separator lines under the help-message headers. If
229- empty, no ruler line is drawn. It defaults to ``'=' ``.
230-
231-
232- .. attribute :: Cmd.use_rawinput
233-
234- A flag, defaulting to true. If true, :meth: `cmdloop ` uses :func: `input ` to
235- display a prompt and read the next command; if false, :data: `sys.stdout.write() <sys.stdout> `
236- and :data: `sys.stdin.readline() <sys.stdin> ` are used. (This means that by importing
237- :mod: `readline `, on systems that support it, the interpreter will automatically
238- support :program: `Emacs `\ -like line editing and command-history keystrokes.)
239-
240-
241- .. _cmd-example :
242-
243- Cmd Example
244- -----------
245-
246- .. sectionauthor :: Raymond Hettinger <python at rcn dot com>
247-
248- The :mod: `cmd ` module is mainly useful for building custom shells that let a
249- user work with a program interactively.
250-
251- This section presents a simple example of how to build a shell around a few of
252- the commands in the :mod: `turtle ` module.
253-
254- Basic turtle commands such as :meth: `~turtle.forward ` are added to a
255- :class: `Cmd ` subclass with method named :meth: `!do_forward `. The argument is
256- converted to a number and dispatched to the turtle module. The docstring is
257- used in the help utility provided by the shell.
258-
259- The example also includes a basic record and playback facility implemented with
260- the :meth: `~Cmd.precmd ` method which is responsible for converting the input to
261- lowercase and writing the commands to a file. The :meth: `!do_playback ` method
262- reads the file and adds the recorded commands to the :attr: `~Cmd.cmdqueue ` for
263- immediate playback::
264-
265- import cmd, sys
266- from turtle import *
267-
268- class TurtleShell(cmd.Cmd):
269- intro = 'Welcome to the turtle shell. Type help or ? to list commands.\n'
270- prompt = '(turtle) '
271- file = None
272-
273- # ----- basic turtle commands -----
274- def do_forward(self, arg):
275- 'Move the turtle forward by the specified distance: FORWARD 10'
276- forward(*parse(arg))
277- def do_right(self, arg):
278- 'Turn turtle right by given number of degrees: RIGHT 20'
279- right(*parse(arg))
280- def do_left(self, arg):
281- 'Turn turtle left by given number of degrees: LEFT 90'
282- left(*parse(arg))
283- def do_goto(self, arg):
284- 'Move turtle to an absolute position with changing orientation. GOTO 100 200'
285- goto(*parse(arg))
286- def do_home(self, arg):
287- 'Return turtle to the home position: HOME'
288- home()
289- def do_circle(self, arg):
290- 'Draw circle with given radius an options extent and steps: CIRCLE 50'
291- circle(*parse(arg))
292- def do_position(self, arg):
293- 'Print the current turtle position: POSITION'
294- print('Current position is %d %d\n' % position())
295- def do_heading(self, arg):
296- 'Print the current turtle heading in degrees: HEADING'
297- print('Current heading is %d\n' % (heading(),))
298- def do_color(self, arg):
299- 'Set the color: COLOR BLUE'
300- color(arg.lower())
301- def do_undo(self, arg):
302- 'Undo (repeatedly) the last turtle action(s): UNDO'
303- def do_reset(self, arg):
304- 'Clear the screen and return turtle to center: RESET'
305- reset()
306- def do_bye(self, arg):
307- 'Stop recording, close the turtle window, and exit: BYE'
308- print('Thank you for using Turtle')
309- self.close()
310- bye()
311- return True
312-
313- # ----- record and playback -----
314- def do_record(self, arg):
315- 'Save future commands to filename: RECORD rose.cmd'
316- self.file = open(arg, 'w')
317- def do_playback(self, arg):
318- 'Playback commands from a file: PLAYBACK rose.cmd'
319- self.close()
320- with open(arg) as f:
321- self.cmdqueue.extend(f.read().splitlines())
322- def precmd(self, line):
323- line = line.lower()
324- if self.file and 'playback' not in line:
325- print(line, file=self.file)
326- return line
327- def close(self):
328- if self.file:
329- self.file.close()
330- self.file = None
331-
332- def parse(arg):
333- 'Convert a series of zero or more numbers to an argument tuple'
334- return tuple(map(int, arg.split()))
335-
336- if __name__ == '__main__':
337- TurtleShell().cmdloop()
338-
339-
340- Here is a sample session with the turtle shell showing the help functions, using
341- blank lines to repeat commands, and the simple record and playback facility:
342-
343- .. code-block :: none
344-
345- Welcome to the turtle shell. Type help or ? to list commands.
346-
347- (turtle) ?
348-
349- Documented commands (type help <topic>):
350- ========================================
351- bye color goto home playback record right
352- circle forward heading left position reset undo
353-
354- (turtle) help forward
355- Move the turtle forward by the specified distance: FORWARD 10
356- (turtle) record spiral.cmd
357- (turtle) position
358- Current position is 0 0
359-
360- (turtle) heading
361- Current heading is 0
362-
363- (turtle) reset
364- (turtle) circle 20
365- (turtle) right 30
366- (turtle) circle 40
367- (turtle) right 30
368- (turtle) circle 60
369- (turtle) right 30
370- (turtle) circle 80
371- (turtle) right 30
372- (turtle) circle 100
373- (turtle) right 30
374- (turtle) circle 120
375- (turtle) right 30
376- (turtle) circle 120
377- (turtle) heading
378- Current heading is 180
379-
380- (turtle) forward 100
381- (turtle)
382- (turtle) right 90
383- (turtle) forward 100
384- (turtle)
385- (turtle) right 90
386- (turtle) forward 400
387- (turtle) right 90
388- (turtle) forward 500
389- (turtle) right 90
390- (turtle) forward 400
391- (turtle) right 90
392- (turtle) forward 300
393- (turtle) playback spiral.cmd
394- Current position is 0 0
395-
396- Current heading is 0
397-
398- Current heading is 180
399-
400- (turtle) bye
401- Thank you for using Turtle
0 commit comments