eryksun added the comment: Testing getpass shouldn't be that difficult if you use ctypes to call WriteConsoleInput [1]. For example:
from ctypes import * from ctypes.wintypes import * kernel32 = WinDLL('kernel32') IN, OUT, INOUT = 1, 2, 3 KEY_EVENT = 0x0001 STD_INPUT_HANDLE = -10 STD_OUTPUT_HANDLE = -11 STD_ERROR_HANDLE = -12 INVALID_HANDLE_VALUE = HANDLE(-1).value class KEY_EVENT_RECORD(Structure): class UCHAR(Union): _fields_ = (('UnicodeChar', WCHAR), ('AsciiChar', CHAR)) _fields_ = (('bKeyDown', BOOL), ('wRepeatCount', WORD), ('wVirtualKeyCode', WORD), ('wVirtualScanCode', WORD), ('uChar', UCHAR), ('dwControlKeyState', DWORD)) class INPUT_RECORD(Structure): class EVENT(Union): _fields_ = (('KeyEvent', KEY_EVENT_RECORD),) _fields_ = (('EventType', WORD), ('Event', EVENT)) PINPUT_RECORD = POINTER(INPUT_RECORD) class HANDLE_IHV(HANDLE): @classmethod def _check_retval_(cls, retval): if retval.value == INVALID_HANDLE_VALUE: raise WinError(get_last_error()) return retval.value def errcheck_bool(result, func, args): if not result: raise WinError(get_last_error()) return args def WINAPI(name, dll, restype, *argspec): if argspec: argtypes = tuple(p[0] for p in argspec) paramflags = tuple(p[1:] for p in argspec) else: argtypes = paramflags = () prototype = WINFUNCTYPE(restype, *argtypes, use_last_error=True) func = prototype((name, dll), paramflags) if restype in (BOOL, HANDLE): func.errcheck = errcheck_bool setattr(dll, name, func) WINAPI('GetStdHandle', kernel32, HANDLE_IHV, (DWORD, IN, 'nStdHandle')) WINAPI('WriteConsoleInputW', kernel32, BOOL, (HANDLE, IN, 'hConsoleInput'), (PINPUT_RECORD, IN, 'lpBuffer'), (DWORD, IN, 'nLength'), (LPDWORD, OUT, 'lpNumberOfEventsWritten')) def write_console_input(s): hInput = kernel32.GetStdHandle(STD_INPUT_HANDLE) recs = (INPUT_RECORD * len(s))() for c, rec in zip(s, recs): rec.EventType = KEY_EVENT rec.Event.KeyEvent.bKeyDown = True rec.Event.KeyEvent.wRepeatCount = 1 rec.Event.KeyEvent.uChar.UnicodeChar = c return kernel32.WriteConsoleInputW(hInput, recs, len(recs)) if __name__ == '__main__': import getpass test_input = 'Console test input.\n' n = write_console_input(test_input) assert n == len(test_input) read_input = getpass.getpass() assert read_input == test_input.rstrip() This requires that python.exe is run with an attached console (conhost.exe), i.e. the process can't be created as a DETACHED_PROCESS [2] nor can it be run using pythonw.exe without first calling AllocConsole. [1]: https://msdn.microsoft.com/en-us/library/ms687403 [2]: https://msdn.microsoft.com/en-us/library/ms684863 ---------- _______________________________________ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue23995> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com