Author: svn-role
Date: Wed Dec 16 04:00:27 2020
New Revision: 1884484

URL: http://svn.apache.org/viewvc?rev=1884484&view=rev
Log:
Merge r1883337 from trunk:

 * r1883337
   Remove uses of os.dup2() from run_tests.py in order to adapt the new
   console reader and writer on Windows since Python 3.6.
   Justification:
     PYTHONLEGACYWINDOWSSTDIO is no longer needed to run unit tests on Windows.
   Votes:
     +1: jun66j5, jcorvel

Modified:
    subversion/branches/1.14.x/   (props changed)
    subversion/branches/1.14.x/STATUS
    subversion/branches/1.14.x/build/run_tests.py
    subversion/branches/1.14.x/subversion/tests/cmdline/svntest/main.py

Propchange: subversion/branches/1.14.x/
------------------------------------------------------------------------------
  Merged /subversion/trunk:r1883337

Modified: subversion/branches/1.14.x/STATUS
URL: 
http://svn.apache.org/viewvc/subversion/branches/1.14.x/STATUS?rev=1884484&r1=1884483&r2=1884484&view=diff
==============================================================================
--- subversion/branches/1.14.x/STATUS (original)
+++ subversion/branches/1.14.x/STATUS Wed Dec 16 04:00:27 2020
@@ -110,11 +110,3 @@ Veto-blocked changes:
 
 Approved changes:
 =================
-
- * r1883337
-   Remove uses of os.dup2() from run_tests.py in order to adapt the new
-   console reader and writer on Windows since Python 3.6.
-   Justification:
-     PYTHONLEGACYWINDOWSSTDIO is no longer needed to run unit tests on Windows.
-   Votes:
-     +1: jun66j5, jcorvel

Modified: subversion/branches/1.14.x/build/run_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/branches/1.14.x/build/run_tests.py?rev=1884484&r1=1884483&r2=1884484&view=diff
==============================================================================
--- subversion/branches/1.14.x/build/run_tests.py (original)
+++ subversion/branches/1.14.x/build/run_tests.py Wed Dec 16 04:00:27 2020
@@ -47,7 +47,7 @@ and filename of a test program, optional
 separated list of test numbers; the default is to run all the tests in it.
 '''
 
-import os, sys, shutil, codecs
+import os, sys, shutil
 import re
 import logging
 import optparse, subprocess, threading, traceback
@@ -141,6 +141,18 @@ def ensure_str(s):
   else:
     return s.decode("latin-1")
 
+def open_logfile(filename, mode, encoding='utf-8'):
+  if sys.version_info[0] != 2:
+    return open(filename, mode, encoding=encoding, errors='surrogateescape')
+  else:
+    class Wrapper(object):
+      def __init__(self, stream, encoding):
+        self._stream = stream
+        self.encoding = encoding
+      def __getattr__(self, name):
+        return getattr(self._stream, name)
+    return Wrapper(open(filename, mode), encoding)
+
 class TestHarness:
   '''Test harness for Subversion tests.
   '''
@@ -700,7 +712,7 @@ class TestHarness:
     # Copy the truly interesting verbose logs to a separate file, for easier
     # viewing.
     if xpassed or failed_list:
-      faillog = codecs.open(self.faillogfile, 'w', encoding="latin-1")
+      faillog = open_logfile(self.faillogfile, 'w')
       last_start_lineno = None
       last_start_re = re.compile('^(FAIL|SKIP|XFAIL|PASS|START|CLEANUP|END):')
       for lineno, line in enumerate(log_lines):
@@ -733,7 +745,7 @@ class TestHarness:
     'Open the log file with the required MODE.'
     if self.logfile:
       self._close_log()
-      self.log = codecs.open(self.logfile, mode, encoding="latin-1")
+      self.log = open_logfile(self.logfile, mode)
 
   def _close_log(self):
     'Close the log file.'
@@ -843,14 +855,13 @@ class TestHarness:
       sys.exit(1)
 
     # setup the output pipes
+    old_stdout = sys.stdout.fileno()
     if self.log:
       sys.stdout.flush()
       sys.stderr.flush()
       self.log.flush()
-      old_stdout = os.dup(sys.stdout.fileno())
-      old_stderr = os.dup(sys.stderr.fileno())
-      os.dup2(self.log.fileno(), sys.stdout.fileno())
-      os.dup2(self.log.fileno(), sys.stderr.fileno())
+      saved_stds = sys.stdout, sys.stderr
+      sys.stdout = sys.stderr = self.log
 
     # These have to be class-scoped for use in the progress_func()
     self.dots_written = 0
@@ -891,12 +902,8 @@ class TestHarness:
 
     # restore some values
     if self.log:
-      sys.stdout.flush()
-      sys.stderr.flush()
-      os.dup2(old_stdout, sys.stdout.fileno())
-      os.dup2(old_stderr, sys.stderr.fileno())
-      os.close(old_stdout)
-      os.close(old_stderr)
+      self.log.flush()
+      sys.stdout, sys.stderr = saved_stds
 
     return failed
 

Modified: subversion/branches/1.14.x/subversion/tests/cmdline/svntest/main.py
URL: 
http://svn.apache.org/viewvc/subversion/branches/1.14.x/subversion/tests/cmdline/svntest/main.py?rev=1884484&r1=1884483&r2=1884484&view=diff
==============================================================================
--- subversion/branches/1.14.x/subversion/tests/cmdline/svntest/main.py 
(original)
+++ subversion/branches/1.14.x/subversion/tests/cmdline/svntest/main.py Wed Dec 
16 04:00:27 2020
@@ -2080,6 +2080,23 @@ class AbbreviatedFormatter(logging.Forma
     record.levelshort = self._level_short[record.levelno]
     return logging.Formatter.format(self, record)
 
+
+class LoggingStdoutHandler(logging.StreamHandler):
+  """
+  The handler is always writing using sys.stdout at call time rather than the
+  value of sys.stdout at construction time.
+
+  Inspired by logging._StderrHandler on Python 3.
+  """
+
+  def __init__(self, level=logging.NOTSET):
+    logging.Handler.__init__(self, level)
+
+  @property
+  def stream(self):
+    return sys.stdout
+
+
 def _create_parser(usage=None):
   """Return a parser for our test suite."""
 
@@ -2272,7 +2289,7 @@ def parse_options(arglist=sys.argv[1:],
                                        datefmt='%Y-%m-%d %H:%M:%S')
     else:
       formatter = AbbreviatedFormatter('%(levelshort)s: %(message)s')
-    handler = logging.StreamHandler(sys.stdout)
+    handler = LoggingStdoutHandler()
     handler.setFormatter(formatter)
     logger.addHandler(handler)
 


Reply via email to