classification
Title: [Windows] test_winconsoleio failures
Type: Stage: resolved
Components: Windows Versions: Python 3.9, Python 3.8
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: eryksun, paul.moore, steve.dower, terry.reedy, tim.golden, zach.ware
Priority: normal Keywords: patch

Created on 2019-09-30 13:20 by vstinner, last changed 2020-09-06 10:10 by vstinner. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 18448 merged vstinner, 2020-02-10 23:37
Messages (7)
msg353571 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2019-09-30 13:20
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
Running Release|x64 interpreter...
== CPython 3.8.0b4+ (heads/pr/16490:8a204fd07c, Sep 30 2019, 14:29:53) [MSC v.1916 64 bit (AMD64)]
== Windows-10-10.0.18362-SP0 little-endian
== cwd: C:\vstinner\python\3.8\build\test_python_1616
== CPU count: 2
== encodings: locale=cp1252, FS=utf-8
Run tests sequentially
0:00:00 [1/1] test_winconsoleio
test_abc (test.test_winconsoleio.WindowsConsoleIOTests) ... ok
test_conin_conout_names (test.test_winconsoleio.WindowsConsoleIOTests) ... ok
test_conout_path (test.test_winconsoleio.WindowsConsoleIOTests) ... ok
test_ctrl_z (test.test_winconsoleio.WindowsConsoleIOTests) ... Ä^Z
ok
test_input (test.test_winconsoleio.WindowsConsoleIOTests) ... abc123
ϼўТλФЙ
A͏B ﬖ̳AA̝
�ERROR
test_open_fd (test.test_winconsoleio.WindowsConsoleIOTests) ... ok
test_open_name (test.test_winconsoleio.WindowsConsoleIOTests) ... ok
test_partial_reads (test.test_winconsoleio.WindowsConsoleIOTests) ... �ERROR
test_partial_surrogate_reads (test.test_winconsoleio.WindowsConsoleIOTests) ... �ERROR
test_write_empty_data (test.test_winconsoleio.WindowsConsoleIOTests) ... ok

======================================================================
ERROR: test_input (test.test_winconsoleio.WindowsConsoleIOTests)
----------------------------------------------------------------------
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

======================================================================
ERROR: test_partial_reads (test.test_winconsoleio.WindowsConsoleIOTests)
----------------------------------------------------------------------
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

======================================================================
ERROR: test_partial_surrogate_reads (test.test_winconsoleio.WindowsConsoleIOTests)
----------------------------------------------------------------------
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

FAILED (errors=3)
test test_winconsoleio failed
test_winconsoleio failed

== Tests result: FAILURE ==

1 test failed:
    test_winconsoleio

Total duration: 62 ms
Tests result: FAILURE
msg353613 - (view) Author: Eryk Sun (eryksun) * (Python triager) Date: 2019-09-30 19:43
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.
msg353616 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2019-09-30 20:03
Until a fix is found, can we mark the tests as "known to fail" on a specific Windows version? (So test_winconsoleio doesn't fail anymore.)
msg353627 - (view) Author: Eryk Sun (eryksun) * (Python triager) Date: 2019-10-01 02:24
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.

> Until a fix is found, can we mark the tests as "known to fail" on a 
> specific Windows version? (So test_winconsoleio doesn't fail anymore.)

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.
msg361758 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2020-02-10 23:58
New changeset 038770edc4680e9a3dc39bacb35a8358034fb901 by Victor Stinner in branch 'master':
bpo-38325: Skip non-BMP tests of test_winconsoleio (GH-18448)
https://github.com/python/cpython/commit/038770edc4680e9a3dc39bacb35a8358034fb901
msg361759 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2020-02-10 23:59
I "fixed" the issue by skipping broken tests. If anyone wants to fix the underlying issue: go ahead and open an issue, it would be way better with a PR to fix these tests!

In the meanwhile, skipping broken tests help to detect regressions (new issues).
msg376450 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2020-09-06 00:00
test_consoleio now fails and hangs for me.  Issue 41729.
History
Date User Action Args
2020-09-06 10:10:37vstinnersetnosy: - vstinner
2020-09-06 00:00:27terry.reedysetnosy: + terry.reedy
messages: + msg376450
2020-02-10 23:59:42vstinnersetstatus: open -> closed
resolution: fixed
messages: + msg361759

stage: patch review -> resolved
2020-02-10 23:58:28vstinnersetmessages: + msg361758
2020-02-10 23:37:47vstinnersetkeywords: + patch
stage: patch review
pull_requests: + pull_request17822
2019-10-01 02:24:47eryksunsetmessages: + msg353627
2019-09-30 20:03:58vstinnersetmessages: + msg353616
2019-09-30 19:43:48eryksunsetnosy: + eryksun
messages: + msg353613
2019-09-30 13:20:15vstinnercreate