On 2020/04/20 9:13, Branko Čibej wrote:
> On 19.04.2020 23:58, Yasuhito FUTATSUKI wrote:
<snip>
>> On 2020/04/19 22:53, Branko Čibej wrote:
>>> On 19.04.2020 14:47, Johan Corveleyn wrote:
>>>> Would you also have an idea on how to fix the PYTHONLEGACYWINDOWSSTDIO
>>>> issue?
>>>> I mean: would it ever be possible to run the testsuite without
>>>> defining that envvar? Or will that remain necessary?
<snip>
>> If reconstruction of _io._WindowsConsoleIO from stored old descripor is
>> allowed (i.e. documented in the specification), it seems to be possible
>> to write work around.
>
>
> Given that these are private symbols, at least according to their names,
> they could change in any minor Python version. :(
Yes, indeed.
However, at least on Python 3.6.6, if given file descptor 1 is pointing
to tty, the result of
open(1, 'w', encoding='utf-8', closefd=False).buffer.raw
is _io._WindowsConsoleIO object, and it seems to be able to used for
console output.
So I wrote a patch for testing (not for commit. it is need to brush up
even if it can work).
At least it should work (no regression) on Python 2.7, Python 3 with
and without PYTHONLEGACYWINDOWSSTDIO on Windows.
(I confirmed on Python 2.7 and Python 3.7 on FreeBSD).
Thanks,
--
Yasuhito FUTATSUKI <[email protected]>
Index: build/run_tests.py
===================================================================
--- build/run_tests.py (revision 1876712)
+++ build/run_tests.py (working copy)
@@ -48,6 +48,7 @@
'''
import os, sys, shutil, codecs
+import io
import re
import logging
import optparse, subprocess, threading, traceback
@@ -844,6 +845,12 @@
# setup the output pipes
if self.log:
+ need_stdout_reconstruct = ( isinstance(sys.stdout, io.IOBase)
+ and not isinstance(sys.stdout.buffer.raw,
+ io.FileIO))
+ need_stderr_reconstruct = ( isinstance(sys.stderr, io.IOBase)
+ and not isinstance(sys.stderr.buffer.raw,
+ io.FileIO))
sys.stdout.flush()
sys.stderr.flush()
self.log.flush()
@@ -851,6 +858,12 @@
old_stderr = os.dup(sys.stderr.fileno())
os.dup2(self.log.fileno(), sys.stdout.fileno())
os.dup2(self.log.fileno(), sys.stderr.fileno())
+ if need_stdout_reconstruct:
+ sys.stdout = open(sys.stdout.fileno(), 'w', encoding='utf-8',
+ errors='replace', closefd=False)
+ if need_stderr_reconstruct:
+ sys.stderr = open(sys.stderr.fileno(), 'w', encoding='utf-8',
+ errors='replace', closefd=False)
# These have to be class-scoped for use in the progress_func()
self.dots_written = 0
@@ -897,6 +910,12 @@
os.dup2(old_stderr, sys.stderr.fileno())
os.close(old_stdout)
os.close(old_stderr)
+ if need_stdout_reconstruct:
+ sys.stdout = open(sys.stdout.fileno(), 'w', encoding='utf-8',
+ errors='replace', closefd=False)
+ if need_stderr_reconstruct:
+ sys.stderr = open(sys.stderr.fileno(), 'w', encoding='utf-8',
+ errors='replace', closefd=False)
return failed