Patchwork D7948: debugcommands: move away from line buffered output on binary stream

login
register
mail settings
Submitter phabricator
Date Jan. 18, 2020, 9:19 p.m.
Message ID <differential-rev-PHID-DREV-yl3qrgxi6zawwvbef5p5-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/44525/
State Superseded
Headers show

Comments

phabricator - Jan. 18, 2020, 9:19 p.m.
indygreg created this revision.
Herald added subscribers: mercurial-devel, mjpieters.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  Line buffering on binary file objects is apparently undefined behavior
  in Python and emits a RuntimeWarning on Python 3.8. See
  https://bugs.python.org/issue32236.
  
  This commit changes the I/O logging file descriptor from line
  buffered to unbuffered to work around this. I'm no fan of
  unbuffered I/O for performance reasons. But I don't think it
  is an issue here given the nature of the code.
  
  With this change, test-ssh-proto.t now passes on Python 3.8.

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D7948

AFFECTED FILES
  mercurial/debugcommands.py

CHANGE DETAILS




To: indygreg, #hg-reviewers
Cc: mjpieters, mercurial-devel

Patch

diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
--- a/mercurial/debugcommands.py
+++ b/mercurial/debugcommands.py
@@ -3218,16 +3218,19 @@ 
         raise error.Abort(_(b'cannot use both --logiofd and --logiofile'))
 
     if opts[b'logiofd']:
-        # Line buffered because output is line based.
+        # Ideally we would be line buffered. But line buffering in binary
+        # mode isn't supported and emits a warning in Python 3.8+. Disabling
+        # buffering could have performance impacts. But since this isn't
+        # performance critical code, it should be fine.
         try:
-            logfh = os.fdopen(int(opts[b'logiofd']), 'ab', 1)
+            logfh = os.fdopen(int(opts[b'logiofd']), 'ab', 0)
         except OSError as e:
             if e.errno != errno.ESPIPE:
                 raise
             # can't seek a pipe, so `ab` mode fails on py3
-            logfh = os.fdopen(int(opts[b'logiofd']), 'wb', 1)
+            logfh = os.fdopen(int(opts[b'logiofd']), 'wb', 0)
     elif opts[b'logiofile']:
-        logfh = open(opts[b'logiofile'], b'ab', 1)
+        logfh = open(opts[b'logiofile'], b'ab', 0)
 
     s = wireprotoserver.sshserver(ui, repo, logfh=logfh)
     s.serve_forever()