From 1bada74bef28f99b175e246e14c4cc356e4889f9 Mon Sep 17 00:00:00 2001 From: Laurent Kislaire Date: Sun, 9 Sep 2018 21:51:10 +0200 Subject: [PATCH 1/5] Fixes #2504 PIL Image.save() requires a string parameter [1] while under python3 we call it with bytes. This leads to wrong format detection (b'.png' isn't a key in supported formats list). [1] https://pillow.readthedocs.io/en/latest/reference/Image.html#PIL.Image.Image.save --- beets/util/artresizer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beets/util/artresizer.py b/beets/util/artresizer.py index e5117a6af..c83d55479 100644 --- a/beets/util/artresizer.py +++ b/beets/util/artresizer.py @@ -72,7 +72,7 @@ def pil_resize(maxwidth, path_in, path_out=None): im = Image.open(util.syspath(path_in)) size = maxwidth, maxwidth im.thumbnail(size, Image.ANTIALIAS) - im.save(path_out) + im.save(util.displayable_path(path_out)) return path_out except IOError: log.error(u"PIL cannot create thumbnail for '{0}'", From f3c48d0a78344355027ed54779d60e4f9e7b05d8 Mon Sep 17 00:00:00 2001 From: Laurent Kislaire Date: Mon, 10 Sep 2018 08:24:50 +0200 Subject: [PATCH 2/5] Using py3_path --- beets/util/artresizer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beets/util/artresizer.py b/beets/util/artresizer.py index c83d55479..e58b356be 100644 --- a/beets/util/artresizer.py +++ b/beets/util/artresizer.py @@ -72,7 +72,7 @@ def pil_resize(maxwidth, path_in, path_out=None): im = Image.open(util.syspath(path_in)) size = maxwidth, maxwidth im.thumbnail(size, Image.ANTIALIAS) - im.save(util.displayable_path(path_out)) + im.save(util.py3_path(path_out)) return path_out except IOError: log.error(u"PIL cannot create thumbnail for '{0}'", From b1fbdc55c855c4fe1d3c87b3806886dbcdc03690 Mon Sep 17 00:00:00 2001 From: Adrian Sampson Date: Mon, 10 Sep 2018 16:09:51 -0400 Subject: [PATCH 3/5] Changelog for #3029 --- docs/changelog.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/changelog.rst b/docs/changelog.rst index 95c774ab3..6195f231a 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -74,6 +74,9 @@ Fixes: * Improve error reporting: during startup if sqlite returns an error the sqlite error message is attached to the beets message. :bug:`3005` +* Fix a problem when resizing images with PIL/Pillow on Python 3. + Thanks to :user:`architek`. + :bug:`2504` :bug:`3029` .. _python-itunes: https://github.com/ocelma/python-itunes From d0ed5cbb9a26e05380f121e9cf9c51e64e6dcac5 Mon Sep 17 00:00:00 2001 From: FichteFoll Date: Thu, 13 Sep 2018 23:42:42 +0200 Subject: [PATCH 4/5] Actually run tests on Python 3.7 --- tox.ini | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tox.ini b/tox.ini index eb678369f..154cd7655 100644 --- a/tox.ini +++ b/tox.ini @@ -40,12 +40,12 @@ passenv = deps = {test,cov}: {[_test]deps} py27: pathlib - py{27,34,35,36}-flake8: {[_flake8]deps} + py{27,34,35,36,37}-flake8: {[_flake8]deps} commands = py27-cov: python -m nose --with-coverage {posargs} py27-test: python -m nose {posargs} - py{34,35}-cov: python -bb -m nose --with-coverage {posargs} - py{34,35,36}-test: python -bb -m nose {posargs} + py3{4,5,6,7}-cov: python -bb -m nose --with-coverage {posargs} + py3{4,5,6,7}-test: python -bb -m nose {posargs} py27-flake8: flake8 --min-version 2.7 {posargs} {[_flake8]files} py34-flake8: flake8 --min-version 3.4 {posargs} {[_flake8]files} py35-flake8: flake8 --min-version 3.5 {posargs} {[_flake8]files} From dc45119a8d1e843fe36ff0ffd031c3b35d48f27d Mon Sep 17 00:00:00 2001 From: Adrian Sampson Date: Sun, 16 Sep 2018 20:52:31 -0400 Subject: [PATCH 5/5] Avoid comparing patterns in a test As pointed out here: https://github.com/beetbox/beets/pull/3028#issuecomment-420257867 --- test/test_ui.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/test/test_ui.py b/test/test_ui.py index 77804d3d2..b9039d236 100644 --- a/test/test_ui.py +++ b/test/test_ui.py @@ -800,16 +800,18 @@ class ConfigTest(unittest.TestCase, TestHelper, _common.Assertions): self.run_command('test', lib=None) replacements = self.test_cmd.lib.replacements - self.assertEqual(replacements, [(re.compile(u'[xy]'), 'z')]) + repls = [(p.pattern, s) for p, s in replacements] # Compare patterns. + self.assertEqual(repls, [(u'[xy]', 'z')]) def test_multiple_replacements_parsed(self): with self.write_config_file() as config: config.write("replace: {'[xy]': z, foo: bar}") self.run_command('test', lib=None) replacements = self.test_cmd.lib.replacements - self.assertEqual(replacements, [ - (re.compile(u'[xy]'), u'z'), - (re.compile(u'foo'), u'bar'), + repls = [(p.pattern, s) for p, s in replacements] + self.assertEqual(repls, [ + (u'[xy]', u'z'), + (u'foo', u'bar'), ]) def test_cli_config_option(self):