KeyboardInterrupt about test for REPL was directly captured by the test program #128676
Open
Description
Bug report
Bug description:
When I was writing test for PR #128467
# under class TestPyReplCompleter(line ≈ 806) Lib/test/test_pyrepl/test_pyrepl.py
def test_completion_menu_cleared_after_KeyboardInterrupt(self):
events = itertools.chain(
code_to_events("int."),
[
Event(evt="key", data="\t", raw=bytearray(b"\t")),
Event(evt="key", data="\t", raw=bytearray(b"\t")),
Event(evt="key", data="\x03", raw=bytearray(b"\x03")), # Ctrl+C
],
)
namespace = {}
reader = self.prepare_reader(events, namespace)
output = multiline_input(reader, namespace)
self.assertEqual(clean_screen(reader.screen), "int.") # asser condition isn't good now
I found the KeyboardInterrupt
caused by Event(evt="key", data="\x03", raw=bytearray(b"\x03"))
will be directly captured by the test program itself
# result of ".\python.bat -m test test_pyrepl.test_pyrepl -v"
== Tests result: INTERRUPTED ==
1 test omitted:
test_pyrepl.test_pyrepl
Test suite interrupted by signal SIGINT.
Total duration: 1.3 sec
Total tests: run=0
Total test files: run=0/1
Result: INTERRUPTED
So I added a traceback in the test function
def test_completion_menu_cleared_after_KeyboardInterrupt(self):
events = itertools.chain(
code_to_events("int."),
[
Event(evt="key", data="\t", raw=bytearray(b"\t")),
Event(evt="key", data="\t", raw=bytearray(b"\t")),
Event(evt="key", data="\x03", raw=bytearray(b"\x03")), # Ctrl+C
],
)
namespace = {}
reader = self.prepare_reader(events, namespace)
try:
output = multiline_input(reader, namespace)
except KeyboardInterrupt:
traceback.print_exc()
self.assertEqual(clean_screen(reader.screen), "int.")
I also added traceback.print_exc()
in Lib/_pyrepl/simple_interact.py(line ≈ 164)
(the user-facing REPL)
except KeyboardInterrupt:
traceback.print_exc() # here
r = _get_reader()
if r.input_trans is r.isearch_trans:
r.do_cmd(("isearch-end", [""]))
if r.cmpltn_menu_choices:
r.cmpltn_reset()
r.pos = len(r.get_unicode())
r.dirty = True
r.refresh()
r.in_bracketed_paste = False
console.write("\nKeyboardInterrupt\n")
console.resetbuffer()
recompile and run
Python 3.14.0a3+ (heads/clean_suggestion-dirty:9801a103467, Jan 9 2025, 14:45:54) [MSC v.1942 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> Traceback (most recent call last):
File "E:\0000__Python_Project\00__cpython\Lib\_pyrepl\simple_interact.py", line 151, in run_multiline_interactive_console
statement = multiline_input(more_lines, ps1, ps2)
File "E:\0000__Python_Project\00__cpython\Lib\_pyrepl\readline.py", line 389, in multiline_input
return reader.readline()
~~~~~~~~~~~~~~~^^
File "E:\0000__Python_Project\00__cpython\Lib\_pyrepl\reader.py", line 801, in readline
self.handle1()
~~~~~~~~~~~~^^
File "E:\0000__Python_Project\00__cpython\Lib\_pyrepl\reader.py", line 756, in handle1
self.console.wait(100)
~~~~~~~~~~~~~~~~~^^^^^
File "E:\0000__Python_Project\00__cpython\Lib\_pyrepl\windows_console.py", line 486, in wait
time.sleep(0.01)
~~~~~~~~~~^^^^^^
KeyboardInterrupt
KeyboardInterrupt
>>>
At the same time, the related error in the test is
File "E:\0000__Python_Project\00__cpython\Lib\test\test_pyrepl\test_pyrepl.py", line 864, in test_completion_menu_cleared_after_KeyboardInterrupt
output = multiline_input(reader, namespace)
File "E:\0000__Python_Project\00__cpython\Lib\test\test_pyrepl\support.py", line 18, in multiline_input
return reader.readline()
~~~~~~~~~~~~~~~^^
File "E:\0000__Python_Project\00__cpython\Lib\_pyrepl\reader.py", line 801, in readline
self.handle1()
~~~~~~~~~~~~^^
File "E:\0000__Python_Project\00__cpython\Lib\_pyrepl\reader.py", line 784, in handle1
self.do_cmd(cmd)
~~~~~~~~~~~^^^^^
File "E:\0000__Python_Project\00__cpython\Lib\_pyrepl\reader.py", line 709, in do_cmd
command.do()
~~~~~~~~~~^^
File "E:\0000__Python_Project\00__cpython\Lib\_pyrepl\commands.py", line 227, in do
raise KeyboardInterrupt
KeyboardInterrupt
FAIL
# something...
======================================================================
FAIL: test_completion_menu_cleared_after_KeyboardInterrupt (test.test_pyrepl.test_pyrepl.TestPyReplCompleter.test_completion_menu_cleared_after_KeyboardInterrupt)
----------------------------------------------------------------------
Traceback (most recent call last):
File "E:\0000__Python_Project\00__cpython\Lib\test\test_pyrepl\test_pyrepl.py", line 868, in test_completion_menu_cleared_after_KeyboardInterrupt
self.assertEqual(clean_screen(reader.screen), "int.")
~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 'int.as_integer_ratio( int.denominator [259 chars]int.' != 'int.'
+ int.
- int.as_integer_ratio( int.denominator int.mro()
- int.bit_count( int.from_bytes( int.numerator
- int.bit_length( int.imag int.real
- int.conjugate( int.is_integer( int.to_bytes(
- >>>int.
----------------------------------------------------------------------
So the KeyboardInterrupt
in test did not behave correctly as if the user pressed Ctrl+C
, but was directly captured by the test program
CPython versions tested on:
CPython main branch
Operating systems tested on:
Windows