Skip to content

Commit 1912f94

Browse files
miss-islingtonambv
andauthored
[3.13] gh-116402: Avoid readline in test_builtin TTY input tests (GH-122447) (GH-122472)
(cherry picked from commit 1d8e453) Co-authored-by: Łukasz Langa <[email protected]>
1 parent 11292ab commit 1912f94

File tree

1 file changed

+24
-15
lines changed

1 file changed

+24
-15
lines changed

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
@@ -30,6 +31,7 @@
3031
from operator import neg
3132
from test import support
3233
from test.support import (cpython_only, swap_attr, maybe_get_event_loop_policy)
34+
from test.support.import_helper import import_module
3335
from test.support.os_helper import (EnvironmentVarGuard, TESTFN, unlink)
3436
from test.support.script_helper import assert_python_ok
3537
from test.support.warnings_helper import check_warnings
@@ -2369,7 +2371,8 @@ def child(wpipe):
23692371
print(ascii(input(prompt)), file=wpipe)
23702372
except BaseException as e:
23712373
print(ascii(f'{e.__class__.__name__}: {e!s}'), file=wpipe)
2372-
lines = self.run_child(child, terminal_input + b"\r\n")
2374+
with self.detach_readline():
2375+
lines = self.run_child(child, terminal_input + b"\r\n")
23732376
# Check we did exercise the GNU readline path
23742377
self.assertIn(lines[0], {'tty = True', 'tty = False'})
23752378
if lines[0] != 'tty = True':
@@ -2382,28 +2385,36 @@ def child(wpipe):
23822385
expected = terminal_input.decode(sys.stdin.encoding) # what else?
23832386
self.assertEqual(input_result, expected)
23842387

2385-
def test_input_tty(self):
2386-
# Test input() functionality when wired to a tty (the code path
2387-
# is different and invokes GNU readline if available).
2388-
self.check_input_tty("prompt", b"quux")
2389-
2390-
def skip_if_readline(self):
2388+
@contextlib.contextmanager
2389+
def detach_readline(self):
23912390
# bpo-13886: When the readline module is loaded, PyOS_Readline() uses
23922391
# the readline implementation. In some cases, the Python readline
23932392
# callback rlhandler() is called by readline with a string without
2394-
# non-ASCII characters. Skip tests on non-ASCII characters if the
2395-
# readline module is loaded, since test_builtin is not intended to test
2393+
# non-ASCII characters.
2394+
# Unlink readline temporarily from PyOS_Readline() for those tests,
2395+
# since test_builtin is not intended to test
23962396
# the readline module, but the builtins module.
2397-
if 'readline' in sys.modules:
2398-
self.skipTest("the readline module is loaded")
2397+
if "readline" in sys.modules:
2398+
c = import_module("ctypes")
2399+
fp_api = "PyOS_ReadlineFunctionPointer"
2400+
prev_value = c.c_void_p.in_dll(c.pythonapi, fp_api).value
2401+
c.c_void_p.in_dll(c.pythonapi, fp_api).value = None
2402+
try:
2403+
yield
2404+
finally:
2405+
c.c_void_p.in_dll(c.pythonapi, fp_api).value = prev_value
2406+
else:
2407+
yield
2408+
2409+
def test_input_tty(self):
2410+
# Test input() functionality when wired to a tty
2411+
self.check_input_tty("prompt", b"quux")
23992412

24002413
def test_input_tty_non_ascii(self):
2401-
self.skip_if_readline()
24022414
# Check stdin/stdout encoding is used when invoking PyOS_Readline()
24032415
self.check_input_tty("prompté", b"quux\xc3\xa9", "utf-8")
24042416

24052417
def test_input_tty_non_ascii_unicode_errors(self):
2406-
self.skip_if_readline()
24072418
# Check stdin/stdout error handler is used when invoking PyOS_Readline()
24082419
self.check_input_tty("prompté", b"quux\xe9", "ascii")
24092420

@@ -2413,14 +2424,12 @@ def test_input_tty_null_in_prompt(self):
24132424
'null characters')
24142425

24152426
def test_input_tty_nonencodable_prompt(self):
2416-
self.skip_if_readline()
24172427
self.check_input_tty("prompté", b"quux", "ascii", stdout_errors='strict',
24182428
expected="UnicodeEncodeError: 'ascii' codec can't encode "
24192429
"character '\\xe9' in position 6: ordinal not in "
24202430
"range(128)")
24212431

24222432
def test_input_tty_nondecodable_input(self):
2423-
self.skip_if_readline()
24242433
self.check_input_tty("prompt", b"quux\xe9", "ascii", stdin_errors='strict',
24252434
expected="UnicodeDecodeError: 'ascii' codec can't decode "
24262435
"byte 0xe9 in position 4: ordinal not in "

0 commit comments

Comments
 (0)