From a99d5d2ed2081172a3d486a492319cd87e02d141 Mon Sep 17 00:00:00 2001 From: Adrian Sampson Date: Thu, 19 Jan 2017 11:42:46 -0800 Subject: [PATCH] On Python 3 in tests, record `str` output directly This is a little ugly. Eventually, it would be nice to create a single output stream set up with the appropriate encoding settings *at startup* and use that repeatedly, instead of having `print_` check the settings every time. This output stream could be cleanly replaced with a mock harness for testing. Yet another reason to desire a big "beets context" object... --- beets/ui/__init__.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/beets/ui/__init__.py b/beets/ui/__init__.py index d69870737..df370b52e 100644 --- a/beets/ui/__init__.py +++ b/beets/ui/__init__.py @@ -136,16 +136,22 @@ def print_(*strings, **kwargs): txt += kwargs.get('end', u'\n') # Encode the string and write it to stdout. - txt = txt.encode(_out_encoding(), 'replace') if six.PY2: # On Python 2, sys.stdout expects bytes. - sys.stdout.write(txt) + out = txt.encode(_out_encoding(), 'replace') + sys.stdout.write(out) else: # On Python 3, sys.stdout expects text strings and uses the # exception-throwing encoding error policy. To avoid throwing # errors and use our configurable encoding override, we use the # underlying bytes buffer instead. - sys.stdout.buffer.write(txt) + if hasattr(sys.stdout, 'buffer'): + out = txt.encode(_out_encoding(), 'replace') + sys.stdout.buffer.write(out) + else: + # In our test harnesses (e.g., DummyOut), sys.stdout.buffer + # does not exist. We instead just record the text string. + sys.stdout.write(txt) # Configuration wrappers.