[Windows] test_winconsoleio failures #82506
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
assignee = None closed_at = <Date 2020-02-10.23:59:42.594> created_at = <Date 2019-09-30.13:20:15.398> labels = ['3.8', '3.9', 'OS-windows'] title = '[Windows] test_winconsoleio failures' updated_at = <Date 2020-09-06.10:10:37.114> user = 'https://github.com/vstinner'
activity = <Date 2020-09-06.10:10:37.114> actor = 'vstinner' assignee = 'none' closed = True closed_date = <Date 2020-02-10.23:59:42.594> closer = 'vstinner' components = ['Windows'] creation = <Date 2019-09-30.13:20:15.398> creator = 'vstinner' dependencies =  files =  hgrepos =  issue_num = 38325 keywords = ['patch'] message_count = 7.0 messages = ['353571', '353613', '353616', '353627', '361758', '361759', '376450'] nosy_count = 6.0 nosy_names = ['terry.reedy', 'paul.moore', 'tim.golden', 'zach.ware', 'eryksun', 'steve.dower'] pr_nums = ['18448'] priority = 'normal' resolution = 'fixed' stage = 'resolved' status = 'closed' superseder = None type = None url = 'https://bugs.python.org/issue38325' versions = ['Python 3.8', 'Python 3.9']
The text was updated successfully, but these errors were encountered:
On Windows 10 version 1903, test_winconsoleio even when run from cmd.exe console.
C:\vstinner\python\3.8>python -m test -v test_winconsoleio
Traceback (most recent call last): File "C:\vstinner\python\3.8\lib\test\test_winconsoleio.py", line 148, in test_input self.assertStdinRoundTrip('\U00100000\U0010ffff\U0010fffd') File "C:\vstinner\python\3.8\lib\test\test_winconsoleio.py", line 135, in assertStdinRoundTrip actual = input() OSError: [WinError 87] Paramètre incorrect
Traceback (most recent call last): File "C:\vstinner\python\3.8\lib\test\test_winconsoleio.py", line 161, in test_partial_reads b = stdin.read(read_count) OSError: [WinError 87] Paramètre incorrect
Traceback (most recent call last): File "C:\vstinner\python\3.8\lib\test\test_winconsoleio.py", line 178, in test_partial_surrogate_reads b = stdin.read(read_count) OSError: [WinError 87] Paramètre incorrect
Ran 10 tests in 0.013s
== Tests result: FAILURE ==
1 test failed:
Total duration: 62 ms
Apparently handling non-BMP codes is broken in recent builds of the new console in Windows 10. I see this problem in build 18362 as well. It seems there have been updates that have changed the naive way the console used to handle surrogate codes as just regular UCS-2 codes, and this has disrupted the UTF-16 wide-character API in several ways. This is probably related to the new support for virtual-terminal emulation and pseudoconsoles, since supporting a UTF-8 stream interface has required significant redesign of the console backend.
Low-level ReadConsoleInputW and WriteConsoleInputW still work, but high-level ReadConsoleW now fails if it encounters a non-BMP surrogate pair, i.e. at least two key-event records with the non-BMP character encoded as a UTF-16 surrogate pair. It can be more than two input records depending on the source of input -- WriteConsoleInputW vs pasting from the clipboard -- in terms of KeyDown/KeyUp events or an Alt+Numpad sequence.
There are issues with reading from screen buffers as well. WriteConsoleW can still successfully write non-BMP characters, and these can be copied from the console fine. But ReadConsoleOutputCharacterW can no longer read them. This used to work, but now it 'succeeds with 0 characters read if the screen-buffer region contains a non-BMP character. I checked the lower-level ReadConsoleOutputW function, and it's behaving differently now. It used to read a non-BMP character as two CHAR_INFO records containing the surrogate pair codes, but now it reads a non-BMP character as a single CHAR_INFO record containing a replacement character U+FFFD.
I suppose we need to skip testing non-BMP and surrogate codes if the Windows version is (10, 0, 18362) and above.
Also, _testconsole needs to support FlushConsoleInputBuffer. Every test that calls _testconsole.write_input should be isolated with a try/finally that flushes the input buffer at the end. For example:
write_input(raw, 'spam') try: actual = input() finally: flush_input(raw)
If reading fails, 'spam' will be flushed from the input buffer.
Does test_partial_reads fail for you when run separately? If so, it's for a different reason. Otherwise, there may have been text left in the input buffer from test_input that led to the failure, which is a separate problem that needs to be addressed via FlushConsoleInputBuffer.
Maybe also split out the non-BMP case in test_input to a separate test_non_bmp_input case that's skipped or expected to fail if sys.getwindowsversion() >= (10, 0, 18362).
As to a fix, there's nothing we can do in Python. An issue can be opened at github.com/microsoft/terminal. I wouldn't expect ReadConsoleOutputW to be fixed. But they should be able to fix ReadConsoleW and ReadConsoleOutputCharacterW.