Title: Control keys stop working after pressing Ctrl-C Escape Enter
Type: behavior Stage: resolved
Components: Versions: Python 3.10, Python 3.9, Python 3.8, Python 3.7, Python 3.6
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: monkeyman79, steven.daprano, trey
Priority: normal Keywords:

Created on 2021-01-29 23:35 by trey, last changed 2021-01-30 01:43 by trey. This issue is now closed.

Messages (5)
msg385957 - (view) Author: Trey Hunner (trey) * Date: 2021-01-29 23:35
On Ubuntu Linux 18.04 when I run Python from within a terminal, control keys such as Ctrl-L, Ctrl-A, Ctrl-E, and Ctrl-K work as expected.

However, if I type Ctrl-C Escape Enter (^C followed by Esc followed by Return), control keys stop working as expected. Ctrl-C still causes KeyboardInterrupt to be printed, but pressing Ctrl-L causes "^L" to be shown and Ctrl-A shows "^A".

This happens in Gnome Terminal as well as XTerm both on Ubuntu Linux 18.04. It happens in zsh, bash, tcsh, and sh.

I've reproduced this issue in Python 2.7, 3.6, 3.7, 3.8, 3.9, and 3.10. Some of these Python versions I installed via pyenv, some came from the deadsnakes PPA, and some were preinstalled with Ubuntu.
msg385958 - (view) Author: Trey Hunner (trey) * Date: 2021-01-29 23:57
I got some help investigating via a Twitter thread on this topic:

Here's more context: that combination of keys seems to put readline into vi mode, though it only does so in Python and not inside my system shell.

If I type start to type a line of code (say "2+2") and hit Escape and then type vi commands like 0 or $, the cursor will navigate to the beginning/end of the line as expected in vi mode.

Ctrl-Alt-L clears the screen and typing "Ctrl-A e" enters back into Emacs readline mode.

I can understand how "Ctrl-A v" would cause the Python REPL to enter vi mode, but I don't understand why "Ctrl-C Escape Enter" would cause that.
msg385961 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2021-01-30 00:00
Ctrl-C is a red-herring here. Esc-Enter alone is sufficient to switch control processing.

Tested in Python 2.7 and 3.9 using xfce4-terminal in Fedora:

1. Ctrl-L clears the terminal window;
2. Type Esc-Enter;
3. Ctrl-L now inserts an actual ^L (chr(12) linefeed) instead of being captured by the terminal and clearing the screen.

I am 80% sure this is a *terminal feature* not a Python bug, to allow you to insert control characters into the command line, but I can't reproduce it in bash or find a way to revert back to normal processing.
msg385963 - (view) Author: Tadek Kijkowski (monkeyman79) * Date: 2021-01-30 01:08
This is readline library feature. ESC-enter swithes it to vi mode. Press ESC-e to switch is back to emacs mode. See man readline.
msg385964 - (view) Author: Trey Hunner (trey) * Date: 2021-01-30 01:43
Thank you Steve and Tadek for confirming that this is a readline feature and for pointing me to the readline manual. The note about an ~/.inputrc file lead me to discover (happily) that I could override this behavior by creating a ~/.inputrc file with the following line in it:

"\e\C-M": abort     Stop Esc Enter from entering vi mode in Python REPL

I'm closing this as "not a bug".
Date User Action Args
2021-01-30 01:43:33treysetstatus: open -> closed
resolution: not a bug
messages: + msg385964

stage: resolved
2021-01-30 01:08:18monkeyman79setnosy: + monkeyman79
messages: + msg385963
2021-01-30 00:00:53steven.dapranosetnosy: + steven.daprano
messages: + msg385961
2021-01-29 23:57:29treysetmessages: + msg385958
2021-01-29 23:35:54treycreate