4
4
import asyncio
5
5
import builtins
6
6
import collections
7
+ import contextlib
7
8
import decimal
8
9
import fractions
9
10
import gc
31
32
from operator import neg
32
33
from test import support
33
34
from test .support import (cpython_only , swap_attr , maybe_get_event_loop_policy )
35
+ from test .support .import_helper import import_module
34
36
from test .support .os_helper import (EnvironmentVarGuard , TESTFN , unlink )
35
37
from test .support .script_helper import assert_python_ok
36
38
from test .support .warnings_helper import check_warnings
@@ -2412,7 +2414,8 @@ def child(wpipe):
2412
2414
print (ascii (input (prompt )), file = wpipe )
2413
2415
except BaseException as e :
2414
2416
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 " )
2416
2419
# Check we did exercise the GNU readline path
2417
2420
self .assertIn (lines [0 ], {'tty = True' , 'tty = False' })
2418
2421
if lines [0 ] != 'tty = True' :
@@ -2425,28 +2428,36 @@ def child(wpipe):
2425
2428
expected = terminal_input .decode (sys .stdin .encoding ) # what else?
2426
2429
self .assertEqual (input_result , expected )
2427
2430
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 ):
2434
2433
# bpo-13886: When the readline module is loaded, PyOS_Readline() uses
2435
2434
# the readline implementation. In some cases, the Python readline
2436
2435
# 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
2439
2439
# 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" )
2442
2455
2443
2456
def test_input_tty_non_ascii (self ):
2444
- self .skip_if_readline ()
2445
2457
# Check stdin/stdout encoding is used when invoking PyOS_Readline()
2446
2458
self .check_input_tty ("prompté" , b"quux\xc3 \xa9 " , "utf-8" )
2447
2459
2448
2460
def test_input_tty_non_ascii_unicode_errors (self ):
2449
- self .skip_if_readline ()
2450
2461
# Check stdin/stdout error handler is used when invoking PyOS_Readline()
2451
2462
self .check_input_tty ("prompté" , b"quux\xe9 " , "ascii" )
2452
2463
@@ -2456,14 +2467,12 @@ def test_input_tty_null_in_prompt(self):
2456
2467
'null characters' )
2457
2468
2458
2469
def test_input_tty_nonencodable_prompt (self ):
2459
- self .skip_if_readline ()
2460
2470
self .check_input_tty ("prompté" , b"quux" , "ascii" , stdout_errors = 'strict' ,
2461
2471
expected = "UnicodeEncodeError: 'ascii' codec can't encode "
2462
2472
"character '\\ xe9' in position 6: ordinal not in "
2463
2473
"range(128)" )
2464
2474
2465
2475
def test_input_tty_nondecodable_input (self ):
2466
- self .skip_if_readline ()
2467
2476
self .check_input_tty ("prompt" , b"quux\xe9 " , "ascii" , stdin_errors = 'strict' ,
2468
2477
expected = "UnicodeDecodeError: 'ascii' codec can't decode "
2469
2478
"byte 0xe9 in position 4: ordinal not in "
0 commit comments