Skip to content

Commit df8c902

Browse files
authored
Merge pull request #3122 from zas/fix/genre-deterministic
PICARD-3246: Fix genre tag changing on every reload with equal vote c…
2 parents 0698867 + 319ad54 commit df8c902

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed

picard/track.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ def _genres_to_metadata(genres, limit=None, minusage=0, filters='', join_with=No
358358
genres = genres_filter.filter(genres, minusage=minusage)
359359

360360
# Find most common genres
361-
most_common_genres = genres.most_common(limit)
361+
most_common_genres = sorted(genres.items(), key=lambda x: (-x[1], x[0]))[:limit]
362362
genres_list = [titlecase(name) for name, _count in most_common_genres]
363363
genres_list.sort()
364364

test/test_track.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,3 +192,26 @@ def test_join_with(self):
192192
genres = Counter(pop=6, rock=7, blues=2)
193193
ret = Track._genres_to_metadata(genres, join_with=',')
194194
self.assertEqual(ret, ['Blues,Pop,Rock'])
195+
196+
def test_limit_with_tied_counts(self):
197+
"""Genres with equal counts must be selected deterministically.
198+
199+
Counter.most_common() returns tied items in insertion order, which
200+
can vary depending on the order the API response is parsed. The
201+
result must be the same regardless of insertion order.
202+
See https://community.metabrainz.org/t/genre-keeps-changing/814606
203+
"""
204+
# Simulate two different insertion orders from the API
205+
genres_order1 = Counter()
206+
genres_order1['modern classical'] = 1
207+
genres_order1['electronic'] = 1
208+
genres_order1['pop'] = 1
209+
210+
genres_order2 = Counter()
211+
genres_order2['electronic'] = 1
212+
genres_order2['pop'] = 1
213+
genres_order2['modern classical'] = 1
214+
215+
ret1 = Track._genres_to_metadata(genres_order1, limit=1)
216+
ret2 = Track._genres_to_metadata(genres_order2, limit=1)
217+
self.assertEqual(ret1, ret2)

0 commit comments

Comments
 (0)