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
30
31
from operator import neg
31
32
from test import support
32
33
from test .support import (cpython_only , swap_attr , maybe_get_event_loop_policy )
34
+ from test .support .import_helper import import_module
33
35
from test .support .os_helper import (EnvironmentVarGuard , TESTFN , unlink )
34
36
from test .support .script_helper import assert_python_ok
35
37
from test .support .warnings_helper import check_warnings
@@ -2369,7 +2371,8 @@ def child(wpipe):
2369
2371
print (ascii (input (prompt )), file = wpipe )
2370
2372
except BaseException as e :
2371
2373
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 " )
2373
2376
# Check we did exercise the GNU readline path
2374
2377
self .assertIn (lines [0 ], {'tty = True' , 'tty = False' })
2375
2378
if lines [0 ] != 'tty = True' :
@@ -2382,28 +2385,36 @@ def child(wpipe):
2382
2385
expected = terminal_input .decode (sys .stdin .encoding ) # what else?
2383
2386
self .assertEqual (input_result , expected )
2384
2387
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 ):
2391
2390
# bpo-13886: When the readline module is loaded, PyOS_Readline() uses
2392
2391
# the readline implementation. In some cases, the Python readline
2393
2392
# 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
2396
2396
# 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" )
2399
2412
2400
2413
def test_input_tty_non_ascii (self ):
2401
- self .skip_if_readline ()
2402
2414
# Check stdin/stdout encoding is used when invoking PyOS_Readline()
2403
2415
self .check_input_tty ("prompté" , b"quux\xc3 \xa9 " , "utf-8" )
2404
2416
2405
2417
def test_input_tty_non_ascii_unicode_errors (self ):
2406
- self .skip_if_readline ()
2407
2418
# Check stdin/stdout error handler is used when invoking PyOS_Readline()
2408
2419
self .check_input_tty ("prompté" , b"quux\xe9 " , "ascii" )
2409
2420
@@ -2413,14 +2424,12 @@ def test_input_tty_null_in_prompt(self):
2413
2424
'null characters' )
2414
2425
2415
2426
def test_input_tty_nonencodable_prompt (self ):
2416
- self .skip_if_readline ()
2417
2427
self .check_input_tty ("prompté" , b"quux" , "ascii" , stdout_errors = 'strict' ,
2418
2428
expected = "UnicodeEncodeError: 'ascii' codec can't encode "
2419
2429
"character '\\ xe9' in position 6: ordinal not in "
2420
2430
"range(128)" )
2421
2431
2422
2432
def test_input_tty_nondecodable_input (self ):
2423
- self .skip_if_readline ()
2424
2433
self .check_input_tty ("prompt" , b"quux\xe9 " , "ascii" , stdin_errors = 'strict' ,
2425
2434
expected = "UnicodeDecodeError: 'ascii' codec can't decode "
2426
2435
"byte 0xe9 in position 4: ordinal not in "
0 commit comments