diff --git a/beets/ui/__init__.py b/beets/ui/__init__.py index ae30a9c60..d69870737 100644 --- a/beets/ui/__init__.py +++ b/beets/ui/__init__.py @@ -126,8 +126,7 @@ def print_(*strings, **kwargs): Python 3. The `end` keyword argument behaves similarly to the built-in `print` - (it defaults to a newline). The value should have the same string - type as the arguments. + (it defaults to a newline). """ if not strings: strings = [u''] @@ -136,11 +135,17 @@ def print_(*strings, **kwargs): txt = u' '.join(strings) txt += kwargs.get('end', u'\n') - # Send bytes to the stdout stream on Python 2. + # Encode the string and write it to stdout. + txt = txt.encode(_out_encoding(), 'replace') if six.PY2: - txt = txt.encode(_out_encoding(), 'replace') - - sys.stdout.write(txt) + # On Python 2, sys.stdout expects bytes. + sys.stdout.write(txt) + 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) # Configuration wrappers. diff --git a/docs/changelog.rst b/docs/changelog.rst index 4fa8aa50f..3b920e51a 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -24,6 +24,9 @@ Fixes: * :doc:`/plugins/replaygain`: Fix Python 3 compatibility in the ``bs1770gain`` backend. :bug:`2382` * :doc:`/plugins/bpd`: Report playback times as integer. :bug:`2394` +* On Python 3, the :ref:`terminal_encoding` setting is respected again for + output and printing will no longer crash on systems configured with a + limited encoding. 1.4.3 (January 9, 2017)