python / cpython

The Python programming language
https://www.python.org
Other
62.36k stars 29.95k forks source link

The new REPL fails on Ctrl-C after search #123856

Open serhiy-storchaka opened 1 week ago

serhiy-storchaka commented 1 week ago

How to reproduce:

>>> Traceback (most recent call last):nes[2::2]))
  File "/home/serhiy/py/cpython/Lib/_pyrepl/simple_interact.py", line 148, in run_multiline_interactive_console
    statement = multiline_input(more_lines, ps1, ps2)
  File "/home/serhiy/py/cpython/Lib/_pyrepl/readline.py", line 389, in multiline_input
    return reader.readline()
           ~~~~~~~~~~~~~~~^^
  File "/home/serhiy/py/cpython/Lib/_pyrepl/reader.py", line 800, in readline
    self.handle1()
    ~~~~~~~~~~~~^^
  File "/home/serhiy/py/cpython/Lib/_pyrepl/reader.py", line 755, in handle1
    self.console.wait(100)
    ~~~~~~~~~~~~~~~~~^^^^^
  File "/home/serhiy/py/cpython/Lib/_pyrepl/unix_console.py", line 426, in wait
    or bool(self.pollob.poll(timeout))
            ~~~~~~~~~~~~~~~~^^^^^^^^^
KeyboardInterrupt

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/serhiy/py/cpython/Lib/runpy.py", line 198, in _run_module_as_main
    return _run_code(code, main_globals, None,
                     "__main__", mod_spec)
  File "/home/serhiy/py/cpython/Lib/runpy.py", line 88, in _run_code
    exec(code, run_globals)
    ~~~~^^^^^^^^^^^^^^^^^^^
  File "/home/serhiy/py/cpython/Lib/_pyrepl/__main__.py", line 6, in <module>
    __pyrepl_interactive_console()
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/home/serhiy/py/cpython/Lib/_pyrepl/main.py", line 59, in interactive_console
    run_multiline_interactive_console(console)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^
  File "/home/serhiy/py/cpython/Lib/_pyrepl/simple_interact.py", line 165, in run_multiline_interactive_console
    r.pop_input_trans()
    ~~~~~~~~~~~~~~~~~^^
  File "/home/serhiy/py/cpython/Lib/_pyrepl/reader.py", line 559, in pop_input_trans
    self.input_trans = self.input_trans_stack.pop()
                       ~~~~~~~~~~~~~~~~~~~~~~~~~~^^
IndexError: pop from empty list
rruuaanng commented 1 week ago

How to reproduce:

* Run the interactive interpreter.

* Press .  You should see the "`` (r-search `') ``" prompt.

* Press . You should see the normal REPL prompt "`>>>` ".

* Press . The REPL quits with a traceback.
>>> Traceback (most recent call last):nes[2::2]))
  File "/home/serhiy/py/cpython/Lib/_pyrepl/simple_interact.py", line 148, in run_multiline_interactive_console
    statement = multiline_input(more_lines, ps1, ps2)
  File "/home/serhiy/py/cpython/Lib/_pyrepl/readline.py", line 389, in multiline_input
    return reader.readline()
           ~~~~~~~~~~~~~~~^^
  File "/home/serhiy/py/cpython/Lib/_pyrepl/reader.py", line 800, in readline
    self.handle1()
    ~~~~~~~~~~~~^^
  File "/home/serhiy/py/cpython/Lib/_pyrepl/reader.py", line 755, in handle1
    self.console.wait(100)
    ~~~~~~~~~~~~~~~~~^^^^^
  File "/home/serhiy/py/cpython/Lib/_pyrepl/unix_console.py", line 426, in wait
    or bool(self.pollob.poll(timeout))
            ~~~~~~~~~~~~~~~~^^^^^^^^^
KeyboardInterrupt

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/serhiy/py/cpython/Lib/runpy.py", line 198, in _run_module_as_main
    return _run_code(code, main_globals, None,
                     "__main__", mod_spec)
  File "/home/serhiy/py/cpython/Lib/runpy.py", line 88, in _run_code
    exec(code, run_globals)
    ~~~~^^^^^^^^^^^^^^^^^^^
  File "/home/serhiy/py/cpython/Lib/_pyrepl/__main__.py", line 6, in <module>
    __pyrepl_interactive_console()
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/home/serhiy/py/cpython/Lib/_pyrepl/main.py", line 59, in interactive_console
    run_multiline_interactive_console(console)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^
  File "/home/serhiy/py/cpython/Lib/_pyrepl/simple_interact.py", line 165, in run_multiline_interactive_console
    r.pop_input_trans()
    ~~~~~~~~~~~~~~~~~^^
  File "/home/serhiy/py/cpython/Lib/_pyrepl/reader.py", line 559, in pop_input_trans
    self.input_trans = self.input_trans_stack.pop()
                       ~~~~~~~~~~~~~~~~~~~~~~~~~~^^
IndexError: pop from empty list

Which version of the interpreter does this problem occur in?

rruuaanng commented 1 week ago

What do I need to type into the interpreter to trigger this error?

Running Release|x64 interpreter...
Python 3.14.0a0 (main, Sep  7 2024, 13:56:04) [MSC v.1941 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> (r-search `')
  File "<python-input-0>", line 1
    (r-search `')
    ^
alexprengere commented 1 week ago

It is present in 3.13rc2. You can reproduce by just typing "ctrl+r", "enter", "ctrl+c".

rruuaanng commented 1 week ago

It is present in 3.13rc2. You can reproduce by just typing "ctrl+r", "enter", "ctrl+c".

Okay, I have testing

rruuaanng commented 1 week ago

I typed ctrl+r, enter, ctrl+c in sequence. The following output appeared:

Running Release|x64 interpreter...
Python 3.13.0rc2+ (main, Sep  9 2024, 17:16:57) [MSC v.1941 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(r-search `') Traceback (most recent call last):
  File "E:\code\cc\cpython\alpha\cpython-3.13\Lib\_pyrepl\simple_interact.py", line 148, in run_multiline_interactive_console
    statement = multiline_input(more_lines, ps1, ps2)
  File "E:\code\cc\cpython\alpha\cpython-3.13\Lib\_pyrepl\readline.py", line 389, in multiline_input
    return reader.readline()
           ~~~~~~~~~~~~~~~^^
  File "E:\code\cc\cpython\alpha\cpython-3.13\Lib\_pyrepl\reader.py", line 800, in readline
    self.handle1()
    ~~~~~~~~~~~~^^
  File "E:\code\cc\cpython\alpha\cpython-3.13\Lib\_pyrepl\reader.py", line 783, in handle1
    self.do_cmd(cmd)
    ~~~~~~~~~~~^^^^^
  File "E:\code\cc\cpython\alpha\cpython-3.13\Lib\_pyrepl\reader.py", line 708, in do_cmd
    command.do()
    ~~~~~~~~~~^^
  File "E:\code\cc\cpython\alpha\cpython-3.13\Lib\_pyrepl\historical_reader.py", line 208, in do
    r.console.forgetinput()
    ~~~~~~~~~~~~~~~~~~~~~^^
  File "E:\code\cc\cpython\alpha\cpython-3.13\Lib\_pyrepl\windows_console.py", line 467, in forgetinput
    while self._read_input() is not None:
          ~~~~~~~~~~~~~~~~^^
  File "E:\code\cc\cpython\alpha\cpython-3.13\Lib\_pyrepl\windows_console.py", line 377, in _read_input
    if not ReadConsoleInput(InHandle, rec, 1, read):
           ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^
KeyboardInterrupt

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "E:\code\cc\cpython\alpha\cpython-3.13\Lib\_pyrepl\__main__.py", line 6, in <module>
    __pyrepl_interactive_console()
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "E:\code\cc\cpython\alpha\cpython-3.13\Lib\_pyrepl\main.py", line 59, in interactive_console
    run_multiline_interactive_console(console)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^
  File "E:\code\cc\cpython\alpha\cpython-3.13\Lib\_pyrepl\simple_interact.py", line 164, in run_multiline_interactive_console
    r.console.forgetinput()
    ~~~~~~~~~~~~~~~~~~~~~^^
  File "E:\code\cc\cpython\alpha\cpython-3.13\Lib\_pyrepl\windows_console.py", line 467, in forgetinput
    while self._read_input() is not None:
          ~~~~~~~~~~~~~~~~^^
  File "E:\code\cc\cpython\alpha\cpython-3.13\Lib\_pyrepl\windows_console.py", line 377, in _read_input
    if not ReadConsoleInput(InHandle, rec, 1, read):
serhiy-storchaka commented 1 week ago

GitHub eats text in angle brackets if it is not quoted. I reproduced with a cursor moving key like <Right>, but <Enter> works as well.

Reproduced in the current 3.12 and main branches.

skirpichev commented 1 week ago

Reproduced in the current 3.12 and main branches.

You meant 3.13, right? I confirm.

skirpichev commented 1 week ago

With

diff --git a/Lib/_pyrepl/reader.py b/Lib/_pyrepl/reader.py
index 54bd1ea022..f525e82442 100644
--- a/Lib/_pyrepl/reader.py
+++ b/Lib/_pyrepl/reader.py
@@ -556,7 +556,8 @@ def push_input_trans(self, itrans: input.KeymapTranslator) -> None:
         self.input_trans = itrans

     def pop_input_trans(self) -> None:
-        self.input_trans = self.input_trans_stack.pop()
+        if self.input_trans_stack:
+            self.input_trans = self.input_trans_stack.pop()

     def setpos_from_xy(self, x: int, y: int) -> None:
         """Set pos according to coordinates x, y"""

I've "KeyboardInterrupt" printed instead and a new >>> prompt. Like in basic repl (bah, the difference is that in the basic repl - "KeyboardInterrupt" is in color!).

If this does make sense, I'll make pr.

serhiy-storchaka commented 1 week ago

I do not know whether this is the right fix or just sweeping the issue under a cover.

cc @pablogsal, @lysnikolaou

pablogsal commented 1 week ago

CC @ambv

ambv commented 1 week ago

I'm on it.