0

I find the following often happens to me:

  1. I am using Python in an interactive terminal session
  2. I accidentally type something with unbalanced parentheses
  3. Python gives me a ... prompt, expecting me to enter another line of code
  4. In an attempt to get back to the Python command prompt, I instinctively type ctrl-D (end of transmission character)
  5. Instead of exiting back to the >>> prompt, the Python process quits immediately, losing all the data from my interactive session

I would like this to not happen any more. Therefore my questions are:

  • Is there a way to prevent Python from quitting when ctrl-D is pressed?;

  • This might be wishful thinking, but is there any way I can make ctrl-D take me back to the Python prompt as I keep expecting it to do?

I use Python 3.6 installed with MacPorts on a Mac, but I guess this is a fairly platform-independent question. I believe this installation uses the Gnu Readline library for user interaction in case that's relevant.

  • I’m curious where your reflex to hit Ctrl-D came from here. In what program does it get you out of a sub-prompt like that without quitting? I think the “proper” solution is Ctrl-C, which will register as a KeyboardInterrupt exception and cancel the current prompt. – Daniel H Feb 26 at 0:42
  • @DanielH I am actually not sure, but it probably mostly comes from bash. – Nathaniel Feb 26 at 0:53
0

In basic programs which use 'cooked' mode, such as cat, Ctrl+D is hooked at the tty layer as the eof character – it isn't sent to the process directly but generates an 'EOF' condition, causing the process to suddenly receive a 0-byte result from its read(stdin) call. (The process could just note the condition and continue though.)

In theory, because Python uses Readline, it isn't affected by this; it uses the terminal in 'cbreak' mode and lets Readline perform the handling of all special characters, including Ctrl+D. (That is, pressing the key will just return "\x04" from read, which is then handled internally by Readline bindings.)

However, Readline automatically binds the same control characters that it sees already bound on the tty layer, and has no option to control this from within Python. (Although it has an ~/.inputrc option, it seems to get ignored within Python.)

is there a way to prevent Python from quitting when ctrl-D is pressed?;

So it seems that there is no way to stop Python's readline from handling Ctrl+D as EOF unless the tty layer has eof bound to something else (but not completely unbound). Your only option is to temporar redefine the EOF character to be something else than Ctrl+D at the tty layer (using stty eof), and redefine it to the correct value upon exit.

Try putting this in your $PYTHONSTARTUP file:

if True:
    import atexit, os
    os.system("stty eof ^X")
    atexit.register(lambda: os.system("stty eof ^D"))

(Note that completely undefinning eof won't work here – if Readline finds null, it will assume Ctrl+D by default.)

Independently of the above, if I do type a mismatched parenthesis, what is the correct way to quit the ... prompt and get back to the >>> one without running the code I've entered?

Press Ctrl+C. Python accepts SIGINT to do this, as do most shells.

  • Python has the readline module. You could use it to bind ^D to a no-op in startup. – Daniel H Feb 26 at 0:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.