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..0a2b4cc97 100644 --- a/tox/session.py +++ b/tox/session.py @@ -160,6 +160,9 @@ def popen(self, args, cwd=None, env=None, redirect=True, returnout=False, ignore try: if resultjson and not redirect: assert popen.stderr is None # prevent deadlock + # 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 +170,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: