From 86e11fb5822f22c28363eb4b3cd1b403d7915766 Mon Sep 17 00:00:00 2001 From: Andrew Sultana Date: Wed, 16 Jun 2021 16:30:42 +0100 Subject: [PATCH 1/2] template: fix ifdef bug #3852 involving non-string fields with missing values --- beets/library.py | 2 +- test/test_types_plugin.py | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/beets/library.py b/beets/library.py index 6e13bf82c..dcd5a6a1f 100644 --- a/beets/library.py +++ b/beets/library.py @@ -1753,7 +1753,7 @@ class DefaultTemplateFunctions(object): :param falseval: The string if the condition is false :return: The string, based on condition """ - if self.item.formatted().get(field): + if field in self.item: return trueval if trueval else self.item.formatted().get(field) else: return falseval diff --git a/test/test_types_plugin.py b/test/test_types_plugin.py index 77d6c8bcf..65ad7bee4 100644 --- a/test/test_types_plugin.py +++ b/test/test_types_plugin.py @@ -145,6 +145,39 @@ class TypesPluginTest(unittest.TestCase, TestHelper): with self.assertRaises(ConfigValueError): self.run_command(u'ls') + def test_template_if_def(self): + # Tests for a subtle bug when using %ifdef in templates along with + # types that have truthy default values (e.g. '0', '0.0', 'False') + # https://github.com/beetbox/beets/issues/3852 + self.config['types'] = {'playcount': u'int', 'rating': u'float', + 'starred': u'bool'} + + with_fields = self.add_item(artist=u'prince') + self.modify(u'playcount=10', u'artist=prince') + self.modify(u'rating=5.0', u'artist=prince') + self.modify(u'starred=yes', u'artist=prince') + with_fields.load() + + without_fields = self.add_item(artist=u'britney') + + int_template = u'%ifdef{playcount,Play count: $playcount,Not played}' + self.assertEqual(with_fields.evaluate_template(int_template), + u'Play count: 10') + self.assertEqual(without_fields.evaluate_template(int_template), + u'Not played') + + float_template = u'%ifdef{rating,Rating: $rating,Not rated}' + self.assertEqual(with_fields.evaluate_template(float_template), + u'Rating: 5.0') + self.assertEqual(without_fields.evaluate_template(float_template), + u'Not rated') + + bool_template = u'%ifdef{starred,Starred: $starred,Not starred}' + self.assertIn(with_fields.evaluate_template(bool_template).lower(), + (u'starred: true', u'starred: yes', u'starred: y')) + self.assertEqual(without_fields.evaluate_template(bool_template), + u'Not starred') + def modify(self, *args): return self.run_with_output(u'modify', u'--yes', u'--nowrite', u'--nomove', *args) From 4c865204798dd9be62108cd35270e29c7e87fc1b Mon Sep 17 00:00:00 2001 From: Andrew Sultana Date: Wed, 16 Jun 2021 16:50:09 +0100 Subject: [PATCH 2/2] template: update changelog --- docs/changelog.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/changelog.rst b/docs/changelog.rst index 26cf39ee6..69e2f01a7 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -377,6 +377,9 @@ Fixes: * :doc`/reference/cli`: Remove reference to rarfile version in link * Fix :bug:`2873`. Duplicates can now generate checksums. Thanks user:`wisp3rwind` for the pointer to how to solve. Thanks to :user:`arogl`. +* Templates that use ``%ifdef`` now produce the expected behavior when used in + conjunction with non-string fields from the :doc:`/plugins/types`. + :bug:`3852` For plugin developers: