Skip to content

Commit c5a6430

Browse files
ambvblhsing
authored andcommitted
pythongh-116402: Avoid readline in test_builtin TTY input tests (pythonGH-122447)
1 parent 38bbdc3 commit c5a6430

File tree

1 file changed

+24
-15
lines changed

1 file changed

+24
-15
lines changed

Diff for: Lib/test/test_builtin.py

+24-15
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import asyncio
55
import builtins
66
import collections
7+
import contextlib
78
import decimal
89
import fractions
910
import gc
@@ -31,6 +32,7 @@
3132
from operator import neg
3233
from test import support
3334
from test.support import (cpython_only, swap_attr, maybe_get_event_loop_policy)
35+
from test.support.import_helper import import_module
3436
from test.support.os_helper import (EnvironmentVarGuard, TESTFN, unlink)
3537
from test.support.script_helper import assert_python_ok
3638
from test.support.warnings_helper import check_warnings
@@ -2412,7 +2414,8 @@ def child(wpipe):
24122414
print(ascii(input(prompt)), file=wpipe)
24132415
except BaseException as e:
24142416
print(ascii(f'{e.__class__.__name__}: {e!s}'), file=wpipe)
2415-
lines = self.run_child(child, terminal_input + b"\r\n")
2417+
with self.detach_readline():
2418+
lines = self.run_child(child, terminal_input + b"\r\n")
24162419
# Check we did exercise the GNU readline path
24172420
self.assertIn(lines[0], {'tty = True', 'tty = False'})
24182421
if lines[0] != 'tty = True':
@@ -2425,28 +2428,36 @@ def child(wpipe):
24252428
expected = terminal_input.decode(sys.stdin.encoding) # what else?
24262429
self.assertEqual(input_result, expected)
24272430

2428-
def test_input_tty(self):
2429-
# Test input() functionality when wired to a tty (the code path
2430-
# is different and invokes GNU readline if available).
2431-
self.check_input_tty("prompt", b"quux")
2432-
2433-
def skip_if_readline(self):
2431+
@contextlib.contextmanager
2432+
def detach_readline(self):
24342433
# bpo-13886: When the readline module is loaded, PyOS_Readline() uses
24352434
# the readline implementation. In some cases, the Python readline
24362435
# callback rlhandler() is called by readline with a string without
2437-
# non-ASCII characters. Skip tests on non-ASCII characters if the
2438-
# readline module is loaded, since test_builtin is not intended to test
2436+
# non-ASCII characters.
2437+
# Unlink readline temporarily from PyOS_Readline() for those tests,
2438+
# since test_builtin is not intended to test
24392439
# the readline module, but the builtins module.
2440-
if 'readline' in sys.modules:
2441-
self.skipTest("the readline module is loaded")
2440+
if "readline" in sys.modules:
2441+
c = import_module("ctypes")
2442+
fp_api = "PyOS_ReadlineFunctionPointer"
2443+
prev_value = c.c_void_p.in_dll(c.pythonapi, fp_api).value
2444+
c.c_void_p.in_dll(c.pythonapi, fp_api).value = None
2445+
try:
2446+
yield
2447+
finally:
2448+
c.c_void_p.in_dll(c.pythonapi, fp_api).value = prev_value
2449+
else:
2450+
yield
2451+
2452+
def test_input_tty(self):
2453+
# Test input() functionality when wired to a tty
2454+
self.check_input_tty("prompt", b"quux")
24422455

24432456
def test_input_tty_non_ascii(self):
2444-
self.skip_if_readline()
24452457
# Check stdin/stdout encoding is used when invoking PyOS_Readline()
24462458
self.check_input_tty("prompté", b"quux\xc3\xa9", "utf-8")
24472459

24482460
def test_input_tty_non_ascii_unicode_errors(self):
2449-
self.skip_if_readline()
24502461
# Check stdin/stdout error handler is used when invoking PyOS_Readline()
24512462
self.check_input_tty("prompté", b"quux\xe9", "ascii")
24522463

@@ -2456,14 +2467,12 @@ def test_input_tty_null_in_prompt(self):
24562467
'null characters')
24572468

24582469
def test_input_tty_nonencodable_prompt(self):
2459-
self.skip_if_readline()
24602470
self.check_input_tty("prompté", b"quux", "ascii", stdout_errors='strict',
24612471
expected="UnicodeEncodeError: 'ascii' codec can't encode "
24622472
"character '\\xe9' in position 6: ordinal not in "
24632473
"range(128)")
24642474

24652475
def test_input_tty_nondecodable_input(self):
2466-
self.skip_if_readline()
24672476
self.check_input_tty("prompt", b"quux\xe9", "ascii", stdin_errors='strict',
24682477
expected="UnicodeDecodeError: 'ascii' codec can't decode "
24692478
"byte 0xe9 in position 4: ordinal not in "

0 commit comments

Comments
 (0)