diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 560161d91..f6ef60bea 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -5,6 +5,7 @@ Alexandre Conrad Allan Feldman Andrii Soldatenko Anthon van der Neuth +Anthony Sottile Asmund Grammeltwedt Barry Warsaw Bartolome Sanchez Salado diff --git a/changelog/426.bugfix.rst b/changelog/426.bugfix.rst new file mode 100644 index 000000000..caf55dd20 --- /dev/null +++ b/changelog/426.bugfix.rst @@ -0,0 +1 @@ +Write directly to stdout buffer if possible to prevent str vs bytes issues - by @asottile diff --git a/tox/session.py b/tox/session.py index a414b4fee..8341d9ad9 100644 --- a/tox/session.py +++ b/tox/session.py @@ -159,7 +159,12 @@ def popen(self, args, cwd=None, env=None, redirect=True, returnout=False, ignore self.report.logpopen(popen, env=env) try: if resultjson and not redirect: - assert popen.stderr is None # prevent deadlock + if popen.stderr is not None: + # prevent deadlock + raise ValueError("stderr must not be piped here") + # we read binary from the process and must write using a + # binary stream + buf = getattr(sys.stdout, 'buffer', sys.stdout) out = None last_time = time.time() while 1: @@ -167,12 +172,12 @@ def popen(self, args, cwd=None, env=None, redirect=True, returnout=False, ignore # might be no output for a long time with slow tests data = fin.read(1) if data: - sys.stdout.write(data) + buf.write(data) if b'\n' in data or (time.time() - last_time) > 1: # we flush on newlines or after 1 second to # provide quick enough feedback to the user # when printing a dot per test - sys.stdout.flush() + buf.flush() last_time = time.time() elif popen.poll() is not None: if popen.stdout is not None: