From a63ee0e1a7f27710279941bc8dce23de992c694c Mon Sep 17 00:00:00 2001 From: Adrian Sampson Date: Sun, 18 Oct 2020 07:19:21 -0400 Subject: [PATCH 1/4] Try normalizing the dbcore String type Strings were not being normalized, unlike some other types, leading to downstream problems like #3773. --- beets/dbcore/types.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/beets/dbcore/types.py b/beets/dbcore/types.py index 5aa2b9812..abda7adcd 100644 --- a/beets/dbcore/types.py +++ b/beets/dbcore/types.py @@ -207,6 +207,12 @@ class String(Type): sql = u'TEXT' query = query.SubstringQuery + def normalize(self, value): + if value is None: + return self.model_type() + else: + return self.model_type(value) + class Boolean(Type): """A boolean type. From e99becb41ed30025aeeebb100e68e478b947986f Mon Sep 17 00:00:00 2001 From: Adrian Sampson Date: Sun, 18 Oct 2020 07:32:44 -0400 Subject: [PATCH 2/4] Use Unicode in lyrics tests --- test/test_lyrics.py | 63 +++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/test/test_lyrics.py b/test/test_lyrics.py index 833b86b3a..95b094e98 100644 --- a/test/test_lyrics.py +++ b/test/test_lyrics.py @@ -48,71 +48,72 @@ class LyricsPluginTest(unittest.TestCase): lyrics.LyricsPlugin() def test_search_artist(self): - item = Item(artist='Alice ft. Bob', title='song') - self.assertIn(('Alice ft. Bob', ['song']), + item = Item(artist=u'Alice ft. Bob', title=u'song') + self.assertIn((u'Alice ft. Bob', [u'song']), lyrics.search_pairs(item)) - self.assertIn(('Alice', ['song']), + self.assertIn((u'Alice', [u'song']), lyrics.search_pairs(item)) - item = Item(artist='Alice feat Bob', title='song') - self.assertIn(('Alice feat Bob', ['song']), + item = Item(artist=u'Alice feat Bob', title=u'song') + self.assertIn((u'Alice feat Bob', [u'song']), lyrics.search_pairs(item)) - self.assertIn(('Alice', ['song']), + self.assertIn((u'Alice', [u'song']), lyrics.search_pairs(item)) - item = Item(artist='Alice feat. Bob', title='song') - self.assertIn(('Alice feat. Bob', ['song']), + item = Item(artist=u'Alice feat. Bob', title=u'song') + self.assertIn((u'Alice feat. Bob', [u'song']), lyrics.search_pairs(item)) - self.assertIn(('Alice', ['song']), + self.assertIn((u'Alice', [u'song']), lyrics.search_pairs(item)) - item = Item(artist='Alice feats Bob', title='song') - self.assertIn(('Alice feats Bob', ['song']), + item = Item(artist=u'Alice feats Bob', title=u'song') + self.assertIn((u'Alice feats Bob', [u'song']), lyrics.search_pairs(item)) - self.assertNotIn(('Alice', ['song']), + self.assertNotIn((u'Alice', [u'song']), lyrics.search_pairs(item)) - item = Item(artist='Alice featuring Bob', title='song') - self.assertIn(('Alice featuring Bob', ['song']), + item = Item(artist=u'Alice featuring Bob', title=u'song') + self.assertIn((u'Alice featuring Bob', [u'song']), lyrics.search_pairs(item)) - self.assertIn(('Alice', ['song']), + self.assertIn((u'Alice', [u'song']), lyrics.search_pairs(item)) - item = Item(artist='Alice & Bob', title='song') - self.assertIn(('Alice & Bob', ['song']), + item = Item(artist=u'Alice & Bob', title=u'song') + self.assertIn((u'Alice & Bob', [u'song']), lyrics.search_pairs(item)) - self.assertIn(('Alice', ['song']), + self.assertIn((u'Alice', [u'song']), lyrics.search_pairs(item)) - item = Item(artist='Alice and Bob', title='song') - self.assertIn(('Alice and Bob', ['song']), + item = Item(artist=u'Alice and Bob', title=u'song') + self.assertIn((u'Alice and Bob', [u'song']), lyrics.search_pairs(item)) - self.assertIn(('Alice', ['song']), + self.assertIn((u'Alice', [u'song']), lyrics.search_pairs(item)) - item = Item(artist='Alice and Bob', title='song') - self.assertEqual(('Alice and Bob', ['song']), + item = Item(artist=u'Alice and Bob', title=u'song') + self.assertEqual((u'Alice and Bob', [u'song']), list(lyrics.search_pairs(item))[0]) def test_search_artist_sort(self): - item = Item(artist='CHVRCHΞS', title='song', artist_sort='CHVRCHES') - self.assertIn(('CHVRCHΞS', ['song']), + item = Item(artist=u'CHVRCHΞS', title=u'song', artist_sort=u'CHVRCHES') + self.assertIn((u'CHVRCHΞS', [u'song']), lyrics.search_pairs(item)) - self.assertIn(('CHVRCHES', ['song']), + self.assertIn((u'CHVRCHES', [u'song']), lyrics.search_pairs(item)) # Make sure that the original artist name is still the first entry - self.assertEqual(('CHVRCHΞS', ['song']), + self.assertEqual((u'CHVRCHΞS', [u'song']), list(lyrics.search_pairs(item))[0]) - item = Item(artist='横山克', title='song', artist_sort='Masaru Yokoyama') - self.assertIn(('横山克', ['song']), + item = Item(artist=u'横山克', title=u'song', + artist_sort=u'Masaru Yokoyama') + self.assertIn((u'横山克', [u'song']), lyrics.search_pairs(item)) - self.assertIn(('Masaru Yokoyama', ['song']), + self.assertIn((u'Masaru Yokoyama', [u'song']), lyrics.search_pairs(item)) # Make sure that the original artist name is still the first entry - self.assertEqual(('横山克', ['song']), + self.assertEqual((u'横山克', [u'song']), list(lyrics.search_pairs(item))[0]) def test_search_pairs_multi_titles(self): From 29bab249c68d5112b90cb3d4932aeccc53d62bbf Mon Sep 17 00:00:00 2001 From: Adrian Sampson Date: Fri, 23 Oct 2020 10:10:21 -0400 Subject: [PATCH 3/4] Use `null` instead of `model_type()` --- beets/dbcore/types.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beets/dbcore/types.py b/beets/dbcore/types.py index abda7adcd..c85eb1a50 100644 --- a/beets/dbcore/types.py +++ b/beets/dbcore/types.py @@ -209,7 +209,7 @@ class String(Type): def normalize(self, value): if value is None: - return self.model_type() + return self.null else: return self.model_type(value) From 2cbec2d838bd594c8a3be5ba55c889af499b4139 Mon Sep 17 00:00:00 2001 From: Adrian Sampson Date: Mon, 26 Oct 2020 20:25:25 -0400 Subject: [PATCH 4/4] Changelog entry --- docs/changelog.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/changelog.rst b/docs/changelog.rst index e65e6b1e9..49cf86330 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -266,6 +266,10 @@ Fixes: the current track in the queue. Thanks to :user:`aereaux`. :bug:`3722` +* String-typed fields are now normalized to string values, avoiding an + occasional crash when using both the :doc:`/plugins/fetchart` and the + :doc:`/plugins/discogs` together. + :bug:`3773` :bug:`3774` For plugin developers: