Mercurial > hg
changeset 45045:8403cc54bc83
procutil: make mercurial.utils.procutil.stderr unbuffered
For most Mercurial code, it doesn’t make a difference, as the ui object flushes
stderr explicitly (after the change, we could get rid of the explicit flush).
One example where it makes a observable difference is mercurial.util.timed().
Without the patch, the time is not immediately shown on Python 3. With the
patch, it’s shown immediately on all Python versions and platforms.
author | Manuel Jacob <me@manueljacob.de> |
---|---|
date | Sun, 05 Jul 2020 13:09:22 +0200 |
parents | 359884685eab |
children | dd3050227a84 |
files | mercurial/utils/procutil.py tests/test-stdio.py |
diffstat | 2 files changed, 24 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/utils/procutil.py Sun Jul 05 13:05:06 2020 +0200 +++ b/mercurial/utils/procutil.py Sun Jul 05 13:09:22 2020 +0200 @@ -99,6 +99,18 @@ else: stdout = os.fdopen(stdout.fileno(), 'wb', 1) +# stderr should be unbuffered +if pycompat.ispy3: + # On Python 3, buffered streams may expose an underlying raw stream. This is + # definitively the case for the streams initialized by the interpreter. If + # the attribute isn't present, the stream is already unbuffered or doesn't + # expose an underlying raw stream, in which case we use the stream as-is. + stderr = getattr(stderr, 'raw', stderr) +elif pycompat.iswindows: + # On Windows, stderr is buffered at least when connected to a pipe. + stderr = os.fdopen(stderr.fileno(), 'wb', 0) +# On other platforms, stderr is always unbuffered. + findexe = platform.findexe _gethgcmd = platform.gethgcmd
--- a/tests/test-stdio.py Sun Jul 05 13:05:06 2020 +0200 +++ b/tests/test-stdio.py Sun Jul 05 13:09:22 2020 +0200 @@ -100,6 +100,18 @@ test_stdout_ptys_unbuffered ) + def test_stderr_pipes(self): + self._test('stderr', _pipes, UNBUFFERED) + + def test_stderr_ptys(self): + self._test('stderr', _ptys, UNBUFFERED) + + def test_stderr_pipes_unbuffered(self): + self._test('stderr', _pipes, UNBUFFERED, python_args=['-u']) + + def test_stderr_ptys_unbuffered(self): + self._test('stderr', _ptys, UNBUFFERED, python_args=['-u']) + if __name__ == '__main__': import silenttestrunner