Skip to content

Commit b0ae6dd

Browse files
kovanclaude
andcommitted
pythongh-144338: Document emptyline() and do_EOF in cmd module
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 12dbae4 commit b0ae6dd

1 file changed

Lines changed: 72 additions & 0 deletions

File tree

Doc/library/cmd.rst

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ A :class:`Cmd` instance has the following methods:
7070
cursor to the left non-destructively, etc.).
7171

7272
An end-of-file on input is passed back as the string ``'EOF'``.
73+
An interpreter can handle this by defining a ``do_EOF`` method, which
74+
works like any other :meth:`!do_\*` method (see :ref:`the example
75+
<cmd-eof-example>` below).
7376

7477
.. index::
7578
single: ? (question mark); in a command interpreter
@@ -399,3 +402,72 @@ blank lines to repeat commands, and the simple record and playback facility:
399402
400403
(turtle) bye
401404
Thank you for using Turtle
405+
406+
407+
.. _cmd-eof-example:
408+
409+
Handling Empty Lines and End-of-File
410+
------------------------------------
411+
412+
Two behaviors of :class:`Cmd` that often surprise new users are the
413+
handling of empty lines and end-of-file.
414+
415+
By default, pressing :kbd:`Enter` on an empty line repeats the last nonempty
416+
command. This is occasionally useful, but can be surprising --- especially
417+
for commands with side effects. Override :meth:`~Cmd.emptyline` to suppress
418+
this behavior::
419+
420+
def emptyline(self):
421+
pass # Do nothing on empty input
422+
423+
When the user sends an end-of-file character (:kbd:`Control-D` on Unix,
424+
:kbd:`Control-Z` on Windows), the framework dispatches it as a command named
425+
``EOF``. Without a ``do_EOF`` method, this triggers :meth:`~Cmd.default`,
426+
which prints an error message. Define a ``do_EOF`` method to exit
427+
gracefully::
428+
429+
def do_EOF(self, arg):
430+
'Exit on Ctrl+D'
431+
print() # Move to a new line after the ^D
432+
return True # Signal cmdloop() to stop
433+
434+
Here is a minimal shell incorporating both overrides::
435+
436+
import cmd
437+
438+
class HelloShell(cmd.Cmd):
439+
prompt = '(hello) '
440+
441+
def do_greet(self, name):
442+
'Greet someone: GREET [name]'
443+
if name:
444+
print(f'Hello, {name}!')
445+
else:
446+
print('Hello, world!')
447+
448+
def do_quit(self, arg):
449+
'Exit the shell: QUIT'
450+
return True
451+
452+
def emptyline(self):
453+
pass
454+
455+
def do_EOF(self, arg):
456+
'Exit on Ctrl+D'
457+
print()
458+
return True
459+
460+
if __name__ == '__main__':
461+
HelloShell().cmdloop()
462+
463+
An example session, showing that empty lines no longer repeat the previous
464+
command and that :kbd:`Control-D` exits cleanly:
465+
466+
.. code-block:: none
467+
468+
(hello) greet Python
469+
Hello, Python!
470+
(hello)
471+
(hello) greet
472+
Hello, world!
473+
(hello) quit

0 commit comments

Comments
 (0)