py3: silence the final IOError by closing stdout/err slightly early
authorYuya Nishihara <yuya@tcha.org>
Fri, 02 Mar 2018 22:35:20 -0500
changeset 36637 e8c361316803
parent 36636 c263c684da91
child 36638 159b04de5fb0
py3: silence the final IOError by closing stdout/err slightly early Fixes the following test failure: $ hg status >/dev/full abort: No space left on device Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' ... OSError: [Errno 28] No space left on device [120]
mercurial/dispatch.py
--- a/mercurial/dispatch.py	Fri Mar 02 22:10:36 2018 -0500
+++ b/mercurial/dispatch.py	Fri Mar 02 22:35:20 2018 -0500
@@ -105,16 +105,38 @@
         # change the status code and move on.
         except IOError:
             status = -1
+
+    _silencestdio()
     sys.exit(status & 255)
 
 if pycompat.ispy3:
     def _initstdio():
         pass
+
+    def _silencestdio():
+        for fp in (sys.stdout, sys.stderr):
+            # Check if the file is okay
+            try:
+                fp.flush()
+                continue
+            except IOError:
+                pass
+            # Otherwise mark it as closed to silence "Exception ignored in"
+            # message emitted by the interpreter finalizer. Be careful to
+            # not close util.stdout, which may be a fdopen-ed file object and
+            # its close() actually closes the underlying file descriptor.
+            try:
+                fp.close()
+            except IOError:
+                pass
 else:
     def _initstdio():
         for fp in (sys.stdin, sys.stdout, sys.stderr):
             util.setbinary(fp)
 
+    def _silencestdio():
+        pass
+
 def _getsimilar(symbols, value):
     sim = lambda x: difflib.SequenceMatcher(None, value, x).ratio()
     # The cutoff for similarity here is pretty arbitrary. It should