diff --git a/NEWS b/NEWS index 0745302d6..f4bbee24f 100644 --- a/NEWS +++ b/NEWS @@ -33,6 +33,7 @@ * Fix a missing __future__ import in embedart on Python 2.5. * Fix ID3 and MPEG-4 tag names for the album-artist field. * Fix Unicode encoding of album artist, album type, and label. +* Fix crash when "copying" an art file that's already in place. 1.0b9 ----- diff --git a/beets/util/__init__.py b/beets/util/__init__.py index 67a878342..5acce8059 100644 --- a/beets/util/__init__.py +++ b/beets/util/__init__.py @@ -193,9 +193,12 @@ def _assert_not_exists(path, pathmod=None): def copy(path, dest, replace=False, pathmod=None): """Copy a plain file. Permissions are not copied. If dest already - exists, raises an OSError unless replace is True. Paths are - translated to system paths before the syscall. + exists, raises an OSError unless replace is True. Has no effect if + path is the same as dest. Paths are translated to system paths + before the syscall. """ + if samefile(path, dest): + return path = syspath(path) dest = syspath(dest) _assert_not_exists(dest, pathmod) @@ -203,9 +206,11 @@ def copy(path, dest, replace=False, pathmod=None): def move(path, dest, replace=False, pathmod=None): """Rename a file. dest may not be a directory. If dest already - exists, raises an OSError unless replace is True. Paths are - translated to system paths. + exists, raises an OSError unless replace is True. Hos no effect if + path is the same as dest. Paths are translated to system paths. """ + if samefile(path, dest): + return path = syspath(path) dest = syspath(dest) _assert_not_exists(dest, pathmod) diff --git a/test/test_files.py b/test/test_files.py index d99292959..45e3b20d5 100644 --- a/test/test_files.py +++ b/test/test_files.py @@ -399,7 +399,7 @@ class SoftRemoveTest(unittest.TestCase, _common.ExtraAsserts): except OSError: self.fail('OSError when removing path') -class SafeMoveCopyTest(unittest.TestCase): +class SafeMoveCopyTest(unittest.TestCase, _common.ExtraAsserts): def setUp(self): self.path = os.path.join(_common.RSRC, 'testfile') touch(self.path) @@ -420,9 +420,13 @@ class SafeMoveCopyTest(unittest.TestCase): def test_successful_move(self): util.move(self.path, self.dest) + self.assertExists(self.dest) + self.assertNotExists(self.path) def test_successful_copy(self): util.copy(self.path, self.dest) + self.assertExists(self.dest) + self.assertExists(self.path) def test_unsuccessful_move(self): with self.assertRaises(OSError): @@ -432,6 +436,14 @@ class SafeMoveCopyTest(unittest.TestCase): with self.assertRaises(OSError): util.copy(self.path, self.otherpath) + def test_self_move(self): + util.move(self.path, self.path) + self.assertExists(self.path) + + def test_self_copy(self): + util.copy(self.path, self.path) + self.assertExists(self.path) + def suite(): return unittest.TestLoader().loadTestsFromName(__name__)