silence Unidecode warning due to byte string info

This commit is contained in:
Adrian Sampson 2013-01-29 11:30:31 -08:00
parent 902139eeac
commit bbb2193b12
4 changed files with 160 additions and 128 deletions

View file

@ -85,6 +85,24 @@ class AlbumInfo(object):
self.albumdisambig = albumdisambig
self.artist_credit = artist_credit
# Work around a bug in python-musicbrainz-ngs that causes some
# strings to be bytes rather than Unicode.
# https://github.com/alastair/python-musicbrainz-ngs/issues/85
def decode(self, codec='utf8'):
"""Ensure that all string attributes on this object, and the
constituent `TrackInfo` objects, are decoded to Unicode.
"""
for fld in ['album', 'artist', 'albumtype', 'label', 'artist_sort',
'script', 'language', 'country', 'albumstatus',
'albumdisambig', 'artist_credit', 'media']:
value = getattr(self, fld)
if isinstance(value, str):
setattr(self, fld, value.decode(codec, 'ignore'))
if self.tracks:
for track in self.tracks:
track.decode(codec)
class TrackInfo(object):
"""Describes a canonical track present on a release. Appears as part
of an AlbumInfo's ``tracks`` list. Consists of these data members:
@ -120,6 +138,17 @@ class TrackInfo(object):
self.disctitle = disctitle
self.artist_credit = artist_credit
# As above, work around a bug in python-musicbrainz-ngs.
def decode(self, codec='utf8'):
"""Ensure that all string attributes on this object are decoded
to Unicode.
"""
for fld in ['title', 'artist', 'medium', 'artist_sort', 'disctitle',
'artist_credit']:
value = getattr(self, fld)
if isinstance(value, str):
setattr(self, fld, value.decode(codec, 'ignore'))
AlbumMatch = namedtuple('AlbumMatch', ['distance', 'info', 'mapping',
'extra_items', 'extra_tracks'])

View file

@ -121,6 +121,7 @@ def track_info(recording, index=None, medium=None, medium_index=None):
if recording.get('length'):
info.length = int(recording['length'])/(1000.0)
info.decode()
return info
def _set_date_str(info, date_str):
@ -214,6 +215,7 @@ def album_info(release):
first_medium = release['medium-list'][0]
info.media = first_medium.get('format')
info.decode()
return info
def match_album(artist, album, tracks=None, limit=SEARCH_LIMIT):

View file

@ -9,6 +9,7 @@ Changelog
contained "real" apostrophes.
* :doc:`/plugins/replaygain`: On Windows, emit a warning instead of
crashing when analyzing non-ASCII filenames.
* Silence a spurious warning from version 0.04.12 of the Unidecode module.
1.0rc2 (December 31, 2012)
--------------------------

View file

@ -79,44 +79,44 @@ class PluralityTest(unittest.TestCase):
self.assertEqual(l_artist, 'aartist')
self.assertFalse(artist_consensus)
def _make_item(title, track, artist='some artist'):
def _make_item(title, track, artist=u'some artist'):
return Item({
'title': title, 'track': track,
'artist': artist, 'album': 'some album',
'artist': artist, 'album': u'some album',
'length': 1,
'mb_trackid': '', 'mb_albumid': '', 'mb_artistid': '',
})
def _make_trackinfo():
return [
TrackInfo('one', None, 'some artist', length=1, index=1),
TrackInfo('two', None, 'some artist', length=1, index=2),
TrackInfo('three', None, 'some artist', length=1, index=3),
TrackInfo(u'one', None, u'some artist', length=1, index=1),
TrackInfo(u'two', None, u'some artist', length=1, index=2),
TrackInfo(u'three', None, u'some artist', length=1, index=3),
]
class TrackDistanceTest(unittest.TestCase):
def test_identical_tracks(self):
item = _make_item('one', 1)
item = _make_item(u'one', 1)
info = _make_trackinfo()[0]
dist = match.track_distance(item, info, incl_artist=True)
self.assertEqual(dist, 0.0)
def test_different_title(self):
item = _make_item('foo', 1)
item = _make_item(u'foo', 1)
info = _make_trackinfo()[0]
dist = match.track_distance(item, info, incl_artist=True)
self.assertNotEqual(dist, 0.0)
def test_different_artist(self):
item = _make_item('one', 1)
item.artist = 'foo'
item = _make_item(u'one', 1)
item.artist = u'foo'
info = _make_trackinfo()[0]
dist = match.track_distance(item, info, incl_artist=True)
self.assertNotEqual(dist, 0.0)
def test_various_artists_tolerated(self):
item = _make_item('one', 1)
item.artist = 'Various Artists'
item = _make_item(u'one', 1)
item.artist = u'Various Artists'
info = _make_trackinfo()[0]
dist = match.track_distance(item, info, incl_artist=True)
self.assertEqual(dist, 0.0)
@ -133,12 +133,12 @@ class AlbumDistanceTest(unittest.TestCase):
def test_identical_albums(self):
items = []
items.append(_make_item('one', 1))
items.append(_make_item('two', 2))
items.append(_make_item('three', 3))
items.append(_make_item(u'one', 1))
items.append(_make_item(u'two', 2))
items.append(_make_item(u'three', 3))
info = AlbumInfo(
artist = 'some artist',
album = 'some album',
artist = u'some artist',
album = u'some album',
tracks = _make_trackinfo(),
va = False,
album_id = None, artist_id = None,
@ -147,11 +147,11 @@ class AlbumDistanceTest(unittest.TestCase):
def test_incomplete_album(self):
items = []
items.append(_make_item('one', 1))
items.append(_make_item('three', 3))
items.append(_make_item(u'one', 1))
items.append(_make_item(u'three', 3))
info = AlbumInfo(
artist = 'some artist',
album = 'some album',
artist = u'some artist',
album = u'some album',
tracks = _make_trackinfo(),
va = False,
album_id = None, artist_id = None,
@ -163,12 +163,12 @@ class AlbumDistanceTest(unittest.TestCase):
def test_global_artists_differ(self):
items = []
items.append(_make_item('one', 1))
items.append(_make_item('two', 2))
items.append(_make_item('three', 3))
items.append(_make_item(u'one', 1))
items.append(_make_item(u'two', 2))
items.append(_make_item(u'three', 3))
info = AlbumInfo(
artist = 'someone else',
album = 'some album',
artist = u'someone else',
album = u'some album',
tracks = _make_trackinfo(),
va = False,
album_id = None, artist_id = None,
@ -177,12 +177,12 @@ class AlbumDistanceTest(unittest.TestCase):
def test_comp_track_artists_match(self):
items = []
items.append(_make_item('one', 1))
items.append(_make_item('two', 2))
items.append(_make_item('three', 3))
items.append(_make_item(u'one', 1))
items.append(_make_item(u'two', 2))
items.append(_make_item(u'three', 3))
info = AlbumInfo(
artist = 'should be ignored',
album = 'some album',
artist = u'should be ignored',
album = u'some album',
tracks = _make_trackinfo(),
va = True,
album_id = None, artist_id = None,
@ -192,12 +192,12 @@ class AlbumDistanceTest(unittest.TestCase):
def test_comp_no_track_artists(self):
# Some VA releases don't have track artists (incomplete metadata).
items = []
items.append(_make_item('one', 1))
items.append(_make_item('two', 2))
items.append(_make_item('three', 3))
items.append(_make_item(u'one', 1))
items.append(_make_item(u'two', 2))
items.append(_make_item(u'three', 3))
info = AlbumInfo(
artist = 'should be ignored',
album = 'some album',
artist = u'should be ignored',
album = u'some album',
tracks = _make_trackinfo(),
va = True,
album_id = None, artist_id = None,
@ -209,12 +209,12 @@ class AlbumDistanceTest(unittest.TestCase):
def test_comp_track_artists_do_not_match(self):
items = []
items.append(_make_item('one', 1))
items.append(_make_item('two', 2, 'someone else'))
items.append(_make_item('three', 3))
items.append(_make_item(u'one', 1))
items.append(_make_item(u'two', 2, u'someone else'))
items.append(_make_item(u'three', 3))
info = AlbumInfo(
artist = 'some artist',
album = 'some album',
artist = u'some artist',
album = u'some album',
tracks = _make_trackinfo(),
va = True,
album_id = None, artist_id = None,
@ -223,12 +223,12 @@ class AlbumDistanceTest(unittest.TestCase):
def test_tracks_out_of_order(self):
items = []
items.append(_make_item('one', 1))
items.append(_make_item('three', 2))
items.append(_make_item('two', 3))
items.append(_make_item(u'one', 1))
items.append(_make_item(u'three', 2))
items.append(_make_item(u'two', 3))
info = AlbumInfo(
artist = 'some artist',
album = 'some album',
artist = u'some artist',
album = u'some album',
tracks = _make_trackinfo(),
va = False,
album_id = None, artist_id = None,
@ -238,12 +238,12 @@ class AlbumDistanceTest(unittest.TestCase):
def test_two_medium_release(self):
items = []
items.append(_make_item('one', 1))
items.append(_make_item('two', 2))
items.append(_make_item('three', 3))
items.append(_make_item(u'one', 1))
items.append(_make_item(u'two', 2))
items.append(_make_item(u'three', 3))
info = AlbumInfo(
artist = 'some artist',
album = 'some album',
artist = u'some artist',
album = u'some album',
tracks = _make_trackinfo(),
va = False,
album_id = None, artist_id = None,
@ -256,12 +256,12 @@ class AlbumDistanceTest(unittest.TestCase):
def test_per_medium_track_numbers(self):
items = []
items.append(_make_item('one', 1))
items.append(_make_item('two', 2))
items.append(_make_item('three', 1))
items.append(_make_item(u'one', 1))
items.append(_make_item(u'two', 2))
items.append(_make_item(u'three', 1))
info = AlbumInfo(
artist = 'some artist',
album = 'some album',
artist = u'some artist',
album = u'some album',
tracks = _make_trackinfo(),
va = False,
album_id = None, artist_id = None,
@ -375,13 +375,13 @@ class AssignmentTest(unittest.TestCase):
def test_reorder_when_track_numbers_incorrect(self):
items = []
items.append(self.item('one', 1))
items.append(self.item('three', 2))
items.append(self.item('two', 3))
items.append(self.item(u'one', 1))
items.append(self.item(u'three', 2))
items.append(self.item(u'two', 3))
trackinfo = []
trackinfo.append(TrackInfo('one', None))
trackinfo.append(TrackInfo('two', None))
trackinfo.append(TrackInfo('three', None))
trackinfo.append(TrackInfo(u'one', None))
trackinfo.append(TrackInfo(u'two', None))
trackinfo.append(TrackInfo(u'three', None))
mapping, extra_items, extra_tracks = \
match.assign_items(items, trackinfo)
self.assertEqual(extra_items, set())
@ -394,13 +394,13 @@ class AssignmentTest(unittest.TestCase):
def test_order_works_with_invalid_track_numbers(self):
items = []
items.append(self.item('one', 1))
items.append(self.item('three', 1))
items.append(self.item('two', 1))
items.append(self.item(u'one', 1))
items.append(self.item(u'three', 1))
items.append(self.item(u'two', 1))
trackinfo = []
trackinfo.append(TrackInfo('one', None))
trackinfo.append(TrackInfo('two', None))
trackinfo.append(TrackInfo('three', None))
trackinfo.append(TrackInfo(u'one', None))
trackinfo.append(TrackInfo(u'two', None))
trackinfo.append(TrackInfo(u'three', None))
mapping, extra_items, extra_tracks = \
match.assign_items(items, trackinfo)
self.assertEqual(extra_items, set())
@ -413,12 +413,12 @@ class AssignmentTest(unittest.TestCase):
def test_order_works_with_missing_tracks(self):
items = []
items.append(self.item('one', 1))
items.append(self.item('three', 3))
items.append(self.item(u'one', 1))
items.append(self.item(u'three', 3))
trackinfo = []
trackinfo.append(TrackInfo('one', None))
trackinfo.append(TrackInfo('two', None))
trackinfo.append(TrackInfo('three', None))
trackinfo.append(TrackInfo(u'one', None))
trackinfo.append(TrackInfo(u'two', None))
trackinfo.append(TrackInfo(u'three', None))
mapping, extra_items, extra_tracks = \
match.assign_items(items, trackinfo)
self.assertEqual(extra_items, set())
@ -430,12 +430,12 @@ class AssignmentTest(unittest.TestCase):
def test_order_works_with_extra_tracks(self):
items = []
items.append(self.item('one', 1))
items.append(self.item('two', 2))
items.append(self.item('three', 3))
items.append(self.item(u'one', 1))
items.append(self.item(u'two', 2))
items.append(self.item(u'three', 3))
trackinfo = []
trackinfo.append(TrackInfo('one', None))
trackinfo.append(TrackInfo('three', None))
trackinfo.append(TrackInfo(u'one', None))
trackinfo.append(TrackInfo(u'three', None))
mapping, extra_items, extra_tracks = \
match.assign_items(items, trackinfo)
self.assertEqual(extra_items, set([items[1]]))
@ -449,9 +449,9 @@ class AssignmentTest(unittest.TestCase):
# A real-world test case contributed by a user.
def item(i, length):
return Item({
'artist': 'ben harper',
'album': 'burn to shine',
'title': 'ben harper - Burn to Shine ' + str(i),
'artist': u'ben harper',
'album': u'burn to shine',
'title': u'ben harper - Burn to Shine ' + str(i),
'track': i,
'length': length,
'mb_trackid': '', 'mb_albumid': '', 'mb_artistid': '',
@ -473,18 +473,18 @@ class AssignmentTest(unittest.TestCase):
def info(index, title, length):
return TrackInfo(title, None, length=length, index=index)
trackinfo = []
trackinfo.append(info(1, 'Alone', 238.893))
trackinfo.append(info(2, 'The Woman in You', 341.44))
trackinfo.append(info(3, 'Less', 245.59999999999999))
trackinfo.append(info(4, 'Two Hands of a Prayer', 470.49299999999999))
trackinfo.append(info(5, 'Please Bleed', 277.86599999999999))
trackinfo.append(info(6, 'Suzie Blue', 269.30599999999998))
trackinfo.append(info(7, 'Steal My Kisses', 245.36000000000001))
trackinfo.append(info(8, 'Burn to Shine', 214.90600000000001))
trackinfo.append(info(9, 'Show Me a Little Shame', 224.09299999999999))
trackinfo.append(info(10, 'Forgiven', 317.19999999999999))
trackinfo.append(info(11, 'Beloved One', 243.733))
trackinfo.append(info(12, 'In the Lord\'s Arms', 186.13300000000001))
trackinfo.append(info(1, u'Alone', 238.893))
trackinfo.append(info(2, u'The Woman in You', 341.44))
trackinfo.append(info(3, u'Less', 245.59999999999999))
trackinfo.append(info(4, u'Two Hands of a Prayer', 470.49299999999999))
trackinfo.append(info(5, u'Please Bleed', 277.86599999999999))
trackinfo.append(info(6, u'Suzie Blue', 269.30599999999998))
trackinfo.append(info(7, u'Steal My Kisses', 245.36000000000001))
trackinfo.append(info(8, u'Burn to Shine', 214.90600000000001))
trackinfo.append(info(9, u'Show Me a Little Shame', 224.09299999999999))
trackinfo.append(info(10, u'Forgiven', 317.19999999999999))
trackinfo.append(info(11, u'Beloved One', 243.733))
trackinfo.append(info(12, u'In the Lord\'s Arms', 186.13300000000001))
mapping, extra_items, extra_tracks = \
match.assign_items(items, trackinfo)
@ -508,22 +508,22 @@ class ApplyTest(unittest.TestCase, ApplyTestUtil):
self.items.append(Item({}))
trackinfo = []
trackinfo.append(TrackInfo(
'oneNew', 'dfa939ec-118c-4d0f-84a0-60f3d1e6522c', medium=1,
u'oneNew', 'dfa939ec-118c-4d0f-84a0-60f3d1e6522c', medium=1,
medium_index=1, artist_credit='trackArtistCredit',
artist_sort='trackArtistSort', index=1,
))
trackinfo.append(TrackInfo('twoNew',
trackinfo.append(TrackInfo(u'twoNew',
'40130ed1-a27c-42fd-a328-1ebefb6caef4',
medium=2, medium_index=1, index=2))
self.info = AlbumInfo(
tracks = trackinfo,
artist = 'artistNew',
album = 'albumNew',
artist = u'artistNew',
album = u'albumNew',
album_id = '7edb51cb-77d6-4416-a23c-3a8c2994a2c7',
artist_id = 'a6623d39-2d8e-4f70-8242-0a9553b91e50',
artist_credit = 'albumArtistCredit',
artist_sort = 'albumArtistSort',
albumtype = 'album',
artist_credit = u'albumArtistCredit',
artist_sort = u'albumArtistSort',
albumtype = u'album',
va = False,
mediums = 2,
)
@ -620,26 +620,26 @@ class ApplyCompilationTest(unittest.TestCase, ApplyTestUtil):
self.items.append(Item({}))
trackinfo = []
trackinfo.append(TrackInfo(
'oneNew',
u'oneNew',
'dfa939ec-118c-4d0f-84a0-60f3d1e6522c',
'artistOneNew',
u'artistOneNew',
'a05686fc-9db2-4c23-b99e-77f5db3e5282',
index=1,
))
trackinfo.append(TrackInfo(
'twoNew',
u'twoNew',
'40130ed1-a27c-42fd-a328-1ebefb6caef4',
'artistTwoNew',
u'artistTwoNew',
'80b3cf5e-18fe-4c59-98c7-e5bb87210710',
index=2,
))
self.info = AlbumInfo(
tracks = trackinfo,
artist = 'variousNew',
album = 'albumNew',
artist = u'variousNew',
album = u'albumNew',
album_id = '3b69ea40-39b8-487f-8818-04b6eff8c21a',
artist_id = '89ad4ac3-39f7-470e-963a-56509c546377',
albumtype = 'compilation',
albumtype = u'compilation',
va = False,
)
@ -675,73 +675,73 @@ class ApplyCompilationTest(unittest.TestCase, ApplyTestUtil):
class StringDistanceTest(unittest.TestCase):
def test_equal_strings(self):
dist = match.string_dist('Some String', 'Some String')
dist = match.string_dist(u'Some String', u'Some String')
self.assertEqual(dist, 0.0)
def test_different_strings(self):
dist = match.string_dist('Some String', 'Totally Different')
dist = match.string_dist(u'Some String', u'Totally Different')
self.assertNotEqual(dist, 0.0)
def test_punctuation_ignored(self):
dist = match.string_dist('Some String', 'Some.String!')
dist = match.string_dist(u'Some String', u'Some.String!')
self.assertEqual(dist, 0.0)
def test_case_ignored(self):
dist = match.string_dist('Some String', 'sOME sTring')
dist = match.string_dist(u'Some String', u'sOME sTring')
self.assertEqual(dist, 0.0)
def test_leading_the_has_lower_weight(self):
dist1 = match.string_dist('XXX Band Name', 'Band Name')
dist2 = match.string_dist('The Band Name', 'Band Name')
dist1 = match.string_dist(u'XXX Band Name', u'Band Name')
dist2 = match.string_dist(u'The Band Name', u'Band Name')
self.assert_(dist2 < dist1)
def test_parens_have_lower_weight(self):
dist1 = match.string_dist('One .Two.', 'One')
dist2 = match.string_dist('One (Two)', 'One')
dist1 = match.string_dist(u'One .Two.', u'One')
dist2 = match.string_dist(u'One (Two)', u'One')
self.assert_(dist2 < dist1)
def test_brackets_have_lower_weight(self):
dist1 = match.string_dist('One .Two.', 'One')
dist2 = match.string_dist('One [Two]', 'One')
dist1 = match.string_dist(u'One .Two.', u'One')
dist2 = match.string_dist(u'One [Two]', u'One')
self.assert_(dist2 < dist1)
def test_ep_label_has_zero_weight(self):
dist = match.string_dist('My Song (EP)', 'My Song')
dist = match.string_dist(u'My Song (EP)', u'My Song')
self.assertEqual(dist, 0.0)
def test_featured_has_lower_weight(self):
dist1 = match.string_dist('My Song blah Someone', 'My Song')
dist2 = match.string_dist('My Song feat Someone', 'My Song')
dist1 = match.string_dist(u'My Song blah Someone', u'My Song')
dist2 = match.string_dist(u'My Song feat Someone', u'My Song')
self.assert_(dist2 < dist1)
def test_postfix_the(self):
dist = match.string_dist('The Song Title', 'Song Title, The')
dist = match.string_dist(u'The Song Title', u'Song Title, The')
self.assertEqual(dist, 0.0)
def test_postfix_a(self):
dist = match.string_dist('A Song Title', 'Song Title, A')
dist = match.string_dist(u'A Song Title', u'Song Title, A')
self.assertEqual(dist, 0.0)
def test_postfix_an(self):
dist = match.string_dist('An Album Title', 'Album Title, An')
dist = match.string_dist(u'An Album Title', u'Album Title, An')
self.assertEqual(dist, 0.0)
def test_empty_strings(self):
dist = match.string_dist('', '')
dist = match.string_dist(u'', u'')
self.assertEqual(dist, 0.0)
def test_solo_pattern(self):
# Just make sure these don't crash.
match.string_dist('The ', '')
match.string_dist('(EP)', '(EP)')
match.string_dist(', An', '')
match.string_dist(u'The ', u'')
match.string_dist(u'(EP)', u'(EP)')
match.string_dist(u', An', u'')
def test_heuristic_does_not_harm_distance(self):
dist = match.string_dist('Untitled', '[Untitled]')
dist = match.string_dist(u'Untitled', u'[Untitled]')
self.assertEqual(dist, 0.0)
def test_ampersand_expansion(self):
dist = match.string_dist('And', '&')
dist = match.string_dist(u'And', u'&')
self.assertEqual(dist, 0.0)
def test_accented_characters(self):