diff --git a/picard/i18n.py b/picard/i18n.py index 61c38c306b..73cdcb3176 100644 --- a/picard/i18n.py +++ b/picard/i18n.py @@ -245,4 +245,8 @@ def sort_key(string, numeric=False): # scripts. Replace numbers in the sort string with their latin equivalent. if numeric and (IS_MACOS or IS_WIN): string = re.sub(r'\d', _digit_replace, string) - return collator.sortKey(string.replace('\0', '')) + + # On macOS numeric sorting of strings entirely consisting of numeric characters fails + # and always sorts alphabetically (002 < 1). Always prefix with an alphabeticcharacter + # to work around that. + return collator.sortKey('a' + string.replace('\0', '')) diff --git a/test/test_i18n.py b/test/test_i18n.py index 0d1d405079..41f0b0e15d 100644 --- a/test/test_i18n.py +++ b/test/test_i18n.py @@ -82,7 +82,11 @@ def test_sort_key(self): i18n.setup_gettext(localedir, 'de') self.assertTrue(i18n.sort_key('äb') < i18n.sort_key('ac')) self.assertTrue(i18n.sort_key('foo002') < i18n.sort_key('foo1')) + self.assertTrue(i18n.sort_key('002 foo') < i18n.sort_key('1 foo')) self.assertTrue(i18n.sort_key('foo1', numeric=True) < i18n.sort_key('foo002', numeric=True)) + self.assertTrue(i18n.sort_key('004', numeric=True) < i18n.sort_key('5', numeric=True)) + self.assertTrue(i18n.sort_key('0042', numeric=True) < i18n.sort_key('50', numeric=True)) + self.assertTrue(i18n.sort_key('5', numeric=True) < i18n.sort_key('0042', numeric=True)) def test_sort_key_numbers_different_scripts(self): i18n.setup_gettext(localedir, 'en')