Yuya Nishihara a écrit :
> On Wed, 03 Jun 2020 05:46:05 +0200, Manuel Jacob wrote:
> > On 2020-06-03 00:04, Augie Fackler wrote:
> > >> On Jun 2, 2020, at 14:07, Manuel Jacob <m...@manueljacob.de> wrote:
> > >> 
> > >> # HG changeset patch
> > >> # User Manuel Jacob <m...@manueljacob.de>
> > >> # Date 1591120869 -7200
> > >> #      Tue Jun 02 20:01:09 2020 +0200
> > >> # Branch stable
> > >> # Node ID ebbc45544673c33ea3beb887ed4d5230b015102a
> > >> # Parent  91e509a12dbc4cd6cf2dcb9dae3ed383932132ac
> > >> py3: always flush ui streams on Python 3
> > >> 
> > >> On Python 2, we rely on that stdout and stderr are line buffered. 
> > >> Python 3’s
> > >> io module doesn’t offer line buffered binary streams.
> > > 
> > > We use the underlying non-buffer thing though for std{err, out}
> > > though, or so I thought. Are you observing  behavior that this
> > > corrects?
> > 
> > pycompat says:
> > 
> >      stdout = sys.stdout.buffer
> >      stderr = sys.stderr.buffer
> > 
> > They are <_io.BufferedWriter name='<stdout>'> and <_io.BufferedWriter 
> > name='<stderr>'>, respectively.
> > 
> > I observed the error in TortoiseHg, which is a long-running process.
> > 
> > To trigger the problem with the hg command, you would need to do 
> > something slow that prints on `self._fout`, e.g. `hg pull 
> > https://www.mercurial-scm.org/repo/hg --debug`.
> 
> Denis, do you have any idea? My assumption was sys.stdout.buffer was magically
> line-buffered, but it appears not at least with Python 3.8.3 on Linux.

sys.stdout is documented to be line-buffered in interactive mode.
But looking at the implementation of TextIOWrapper, line buffering is
apparently not handled at the underlying buffer level (which we use
IIRC):

  https://github.com/python/cpython/blob/v3.8.3/Lib/_pyio.py#L2210

This would mean that sys.stdout.buffer is not line-buffered.

So perhaps flushing using a similar logic as in TextIOWrapper.write(),
but at the buffer level, is the way go.


> https://www.mercurial-scm.org/repo/hg/rev/227ba1afcb65
> 
> > >> --- a/mercurial/ui.py
> > >> +++ b/mercurial/ui.py
> > >> @@ -1198,9 +1198,14 @@ class ui(object):
> > >>                     label = opts.get('label', b'')
> > >>                     msg = self.label(msg, label)
> > >>                 dest.write(msg)
> > >> +            # On Python 2, stdout and stderr are usually line 
> > >> buffered, but
> > >>             # stderr may be buffered under win32 when redirected to 
> > >> files,
> > >>             # including stdout.
> > >> -            if dest is self._ferr and not getattr(self._ferr, 
> > >> 'closed', False):
> > >> +            # On Python 3, we use the underlying binary buffer, which 
> > >> does not
> > >> +            # support line buffering.
> > >> +            if (pycompat.ispy3 or dest is self._ferr) and not 
> > >> getattr(
> > >> +                self._ferr, 'closed', False
> > >> +            ):
> > >>                 dest.flush()
> 
> Flushing stdout per write() sounds bad. If that's the only way to work
> around Py3 io module, we'll probably need to check if the stdout is
> a tty or not.
_______________________________________________
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel

Reply via email to