|
4 | 4 | import sys |
5 | 5 | import threading |
6 | 6 |
|
| 7 | +from importlib import import_module |
7 | 8 | from test import support |
8 | 9 | from test.support import os_helper |
9 | 10 |
|
@@ -65,17 +66,23 @@ def __init__(self, test_name, verbose, quiet, *, pgo): |
65 | 66 | 'shutil_archive_formats', 'shutil_unpack_formats', |
66 | 67 | 'asyncio.events._event_loop_policy', |
67 | 68 | 'urllib.requests._url_tempfiles', 'urllib.requests._opener', |
| 69 | + 'stty_echo', |
68 | 70 | ) |
69 | 71 |
|
70 | 72 | def get_module(self, name): |
71 | 73 | # function for restore() methods |
72 | 74 | return sys.modules[name] |
73 | 75 |
|
74 | | - def try_get_module(self, name): |
| 76 | + def try_get_module(self, name, *, demand=False): |
75 | 77 | # function for get() methods |
76 | 78 | try: |
77 | 79 | return self.get_module(name) |
78 | 80 | except KeyError: |
| 81 | + if demand: |
| 82 | + try: |
| 83 | + return import_module(name) |
| 84 | + except ModuleNotFoundError: |
| 85 | + pass |
79 | 86 | raise SkipTestEnvironment |
80 | 87 |
|
81 | 88 | def get_urllib_requests__url_tempfiles(self): |
@@ -292,6 +299,25 @@ def restore_warnings_showwarning(self, fxn): |
292 | 299 | warnings = self.get_module('warnings') |
293 | 300 | warnings.showwarning = fxn |
294 | 301 |
|
| 302 | + def get_stty_echo(self): |
| 303 | + termios = self.try_get_module('termios', demand=True) |
| 304 | + if not os.isatty(fd := sys.__stdin__.fileno()): |
| 305 | + return None |
| 306 | + attrs = termios.tcgetattr(fd) |
| 307 | + lflags = attrs[3] |
| 308 | + return bool(lflags & termios.ECHO) |
| 309 | + |
| 310 | + def restore_stty_echo(self, echo): |
| 311 | + termios = self.get_module('termios') |
| 312 | + attrs = termios.tcgetattr(fd := sys.__stdin__.fileno()) |
| 313 | + if echo: |
| 314 | + # Turn echo on. |
| 315 | + attrs[3] |= termios.ECHO |
| 316 | + else: |
| 317 | + # Turn echo off. |
| 318 | + attrs[3] &= ~termios.ECHO |
| 319 | + termios.tcsetattr(fd, termios.TCSADRAIN, attrs) |
| 320 | + |
295 | 321 | def resource_info(self): |
296 | 322 | for name in self.resources: |
297 | 323 | method_suffix = name.replace('.', '_') |
|
0 commit comments