diff --git a/beets/ui/commands.py b/beets/ui/commands.py
index 6adc27786..1ed03bb9e 100755
--- a/beets/ui/commands.py
+++ b/beets/ui/commands.py
@@ -1376,10 +1376,10 @@ def modify_items(lib, mods, dels, query, write, move, album, confirm):
# objects.
print_(u'Modifying {0} {1}s.'
.format(len(objs), u'album' if album else u'item'))
- changed = set()
+ changed = []
for obj in objs:
- if print_and_modify(obj, mods, dels):
- changed.add(obj)
+ if print_and_modify(obj, mods, dels) and obj not in changed:
+ changed.append(obj)
# Still something to do?
if not changed:
diff --git a/docs/changelog.rst b/docs/changelog.rst
index 1c21bf834..d08c0732f 100644
--- a/docs/changelog.rst
+++ b/docs/changelog.rst
@@ -98,9 +98,14 @@ Fixes:
* Missing album art file during an update no longer causes a fatal exception
(instead, an error is logged and the missing file path is removed from the
library). :bug:`3030`
-
+* Fixed the ordering of items when manually selecting changes while updating
+ tags
+ Thanks to :user:`TaizoSimpson`.
+ :bug:`3501`
* Confusing typo when the convert plugin copies the art covers.
+
+
.. _python-itunes: https://github.com/ocelma/python-itunes
diff --git a/test/test_filefilter.py b/test/test_filefilter.py
index e7a4119d4..57310fd2a 100644
--- a/test/test_filefilter.py
+++ b/test/test_filefilter.py
@@ -137,7 +137,7 @@ class FileFilterPluginTest(unittest.TestCase, ImportHelper):
# Global options
def test_import_global(self):
- config['filefilter']['path'] = '.*track_1.*\.mp3'
+ config['filefilter']['path'] = '.*track_1.*\\.mp3'
self.__run([
'Album: %s' % displayable_path(self.artist_path),
' %s' % displayable_path(self.artist_paths[0]),
@@ -151,7 +151,7 @@ class FileFilterPluginTest(unittest.TestCase, ImportHelper):
# Album options
def test_import_album(self):
- config['filefilter']['album_path'] = '.*track_1.*\.mp3'
+ config['filefilter']['album_path'] = '.*track_1.*\\.mp3'
self.__run([
'Album: %s' % displayable_path(self.artist_path),
' %s' % displayable_path(self.artist_paths[0]),
@@ -169,7 +169,7 @@ class FileFilterPluginTest(unittest.TestCase, ImportHelper):
# Singleton options
def test_import_singleton(self):
- config['filefilter']['singleton_path'] = '.*track_1.*\.mp3'
+ config['filefilter']['singleton_path'] = '.*track_1.*\\.mp3'
self.__run([
'Singleton: %s' % displayable_path(self.artist_paths[0]),
'Singleton: %s' % displayable_path(self.misc_paths[0])
@@ -188,8 +188,8 @@ class FileFilterPluginTest(unittest.TestCase, ImportHelper):
# Album and singleton options
def test_import_both(self):
- config['filefilter']['album_path'] = '.*track_1.*\.mp3'
- config['filefilter']['singleton_path'] = '.*track_2.*\.mp3'
+ config['filefilter']['album_path'] = '.*track_1.*\\.mp3'
+ config['filefilter']['singleton_path'] = '.*track_2.*\\.mp3'
self.__run([
'Album: %s' % displayable_path(self.artist_path),
' %s' % displayable_path(self.artist_paths[0]),
diff --git a/test/test_lyrics.py b/test/test_lyrics.py
index 398314ba6..4d48ed9ed 100644
--- a/test/test_lyrics.py
+++ b/test/test_lyrics.py
@@ -165,7 +165,7 @@ class LyricsPluginTest(unittest.TestCase):
one
two !
-
+
"""
self.assertEqual(lyrics._scrape_strip_cruft(text, True),
"one\ntwo !\n\nfour")
diff --git a/test/test_player.py b/test/test_player.py
index 0a576f0ba..523a39d1b 100644
--- a/test/test_player.py
+++ b/test/test_player.py
@@ -60,7 +60,7 @@ class CommandParseTest(unittest.TestCase):
def test_backslash_in_arg(self):
s = r'command "hello \\ there"'
c = bpd.Command(s)
- self.assertEqual(c.args, [u'hello \ there'])
+ self.assertEqual(c.args, [u'hello \\ there'])
def suite():
diff --git a/test/test_the.py b/test/test_the.py
index 72e9bf161..263446b92 100644
--- a/test/test_the.py
+++ b/test/test_the.py
@@ -50,7 +50,7 @@ class ThePluginTest(_common.TestCase):
self.assertEqual(ThePlugin().the_template_func(u'An A'), u'A, An')
def test_custom_pattern(self):
- config['the']['patterns'] = [u'^test\s']
+ config['the']['patterns'] = [u'^test\\s']
config['the']['format'] = FORMAT
self.assertEqual(ThePlugin().the_template_func(u'test passed'),
u'passed, test')