Patchwork [4,of,7] ui: add inner function to select write destination

login
register
mail settings
Submitter Yuya Nishihara
Date Nov. 6, 2018, 2:21 p.m.
Message ID <5b469a4ae6a188168012.1541514093@mimosa>
Download mbox | patch
Permalink /patch/36433/
State Accepted
Headers show

Comments

Yuya Nishihara - Nov. 6, 2018, 2:21 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1541236650 -32400
#      Sat Nov 03 18:17:30 2018 +0900
# Node ID 5b469a4ae6a18816801259a0a4899e2739179f4a
# Parent  a4353cb008c9ca70dc347b6c151f9252ba30d82e
ui: add inner function to select write destination

I'm going to add a config knob to redirect any status messages to stderr.
This function helps to switch underlying file objects.

# no-check-commit because of existing write_err() function

Patch

diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -913,6 +913,13 @@  class ui(object):
 
         return "".join(self._buffers.pop())
 
+    def _isbuffered(self, dest):
+        if dest is self.fout:
+            return bool(self._buffers)
+        if dest is self.ferr:
+            return bool(self._bufferstates and self._bufferstates[-1][0])
+        return False
+
     def canwritewithoutlabels(self):
         '''check if write skips the label'''
         if self._buffers and not self._bufferapplylabels:
@@ -940,14 +947,20 @@  class ui(object):
         "cmdname.type" is recommended. For example, status issues
         a label of "status.modified" for modified files.
         '''
-        if self._buffers:
+        self._write(self.fout, *args, **opts)
+
+    def write_err(self, *args, **opts):
+        self._write(self.ferr, *args, **opts)
+
+    def _write(self, dest, *args, **opts):
+        if self._isbuffered(dest):
             if self._bufferapplylabels:
                 label = opts.get(r'label', '')
                 self._buffers[-1].extend(self.label(a, label) for a in args)
             else:
                 self._buffers[-1].extend(args)
         else:
-            self._writenobuf(self.fout, *args, **opts)
+            self._writenobuf(dest, *args, **opts)
 
     def _writenobuf(self, dest, *args, **opts):
         self._progclear()
@@ -981,12 +994,6 @@  class ui(object):
             self._blockedtimes['stdio_blocked'] += \
                 (util.timer() - starttime) * 1000
 
-    def write_err(self, *args, **opts):
-        if self._bufferstates and self._bufferstates[-1][0]:
-            self.write(*args, **opts)
-        else:
-            self._writenobuf(self.ferr, *args, **opts)
-
     def flush(self):
         # opencode timeblockedsection because this is a critical path
         starttime = util.timer()
diff --git a/tests/test-rollback.t b/tests/test-rollback.t
--- a/tests/test-rollback.t
+++ b/tests/test-rollback.t
@@ -278,11 +278,12 @@  I/O errors on stdio are handled properly
   > 
   > def uisetup(ui):
   >     class badui(ui.__class__):
-  >         def write_err(self, *args, **kwargs):
+  >         def _write(self, dest, *args, **kwargs):
   >             olderr = self.ferr
   >             try:
-  >                 self.ferr = fdproxy(self, olderr)
-  >                 return super(badui, self).write_err(*args, **kwargs)
+  >                 if dest is self.ferr:
+  >                     self.ferr = dest = fdproxy(self, olderr)
+  >                 return super(badui, self)._write(dest, *args, **kwargs)
   >             finally:
   >                 self.ferr = olderr
   >