Merge pull request #3167 from jackwilsdon/fix-hook-unicode

Fix hook byte string interpolation
This commit is contained in:
Adrian Sampson 2019-02-25 11:09:12 -05:00 committed by GitHub
commit f6ad98a4a5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 23 additions and 8 deletions

View file

@ -18,7 +18,6 @@ from __future__ import division, absolute_import, print_function
import string
import subprocess
import six
from beets.plugins import BeetsPlugin
from beets.util import shlex_split, arg_encoding
@ -46,10 +45,8 @@ class CodingFormatter(string.Formatter):
See str.format and string.Formatter.format.
"""
try:
if isinstance(format_string, bytes):
format_string = format_string.decode(self._coding)
except UnicodeEncodeError:
pass
return super(CodingFormatter, self).format(format_string, *args,
**kwargs)
@ -96,10 +93,7 @@ class HookPlugin(BeetsPlugin):
return
# Use a string formatter that works on Unicode strings.
if six.PY2:
formatter = CodingFormatter(arg_encoding())
else:
formatter = string.Formatter()
formatter = CodingFormatter(arg_encoding())
command_pieces = shlex_split(command)

View file

@ -150,6 +150,8 @@ Fixes:
* :doc:`/plugins/badfiles`: Avoid a crash when the underlying tool emits
undecodable output.
:bug:`3165`
* :doc:`/plugins/hook`: Fix byte string interpolation in hook commands.
:bug:`2967` :bug:`3167`
.. _python-itunes: https://github.com/ocelma/python-itunes

View file

@ -110,6 +110,25 @@ class HookTest(_common.TestCase, TestHelper):
self.assertTrue(os.path.isfile(path))
os.remove(path)
def test_hook_bytes_interpolation(self):
temporary_paths = [
get_temporary_path().encode('utf-8')
for i in range(self.TEST_HOOK_COUNT)
]
for index, path in enumerate(temporary_paths):
self._add_hook('test_bytes_event_{0}'.format(index),
'touch "{path}"')
self.load_plugins('hook')
for index, path in enumerate(temporary_paths):
plugins.send('test_bytes_event_{0}'.format(index), path=path)
for path in temporary_paths:
self.assertTrue(os.path.isfile(path))
os.remove(path)
def suite():
return unittest.TestLoader().loadTestsFromName(__name__)