diff --git a/beets/util/__init__.py b/beets/util/__init__.py index d58bb28e44..720ca311a2 100644 --- a/beets/util/__init__.py +++ b/beets/util/__init__.py @@ -479,31 +479,40 @@ def move(path, dest, replace=False): instead, in which case metadata will *not* be preserved. Paths are translated to system paths. """ - if os.path.isdir(path): + if os.path.isdir(syspath(path)): raise FilesystemError(u'source is directory', 'move', (path, dest)) - if os.path.isdir(dest): + if os.path.isdir(syspath(dest)): raise FilesystemError(u'destination is directory', 'move', (path, dest)) if samefile(path, dest): return - path = syspath(path) - dest = syspath(dest) - if os.path.exists(dest) and not replace: + if os.path.exists(syspath(dest)) and not replace: raise FilesystemError('file exists', 'rename', (path, dest)) # First, try renaming the file. try: - os.replace(path, dest) + os.replace(syspath(path), syspath(dest)) except OSError: - tmp = tempfile.mktemp(suffix='.beets', - prefix=py3_path(b'.' + os.path.basename(dest)), - dir=py3_path(os.path.dirname(dest))) - tmp = syspath(tmp) + # Copy the file to a temporary destination. + basename = os.path.basename(bytestring_path(dest)) + dirname = os.path.dirname(bytestring_path(dest)) + tmp = tempfile.NamedTemporaryFile( + suffix=syspath(b'.beets', prefix=False), + prefix=syspath(b'.' + basename, prefix=False), + dir=syspath(dirname), + delete=False, + ) + try: + with open(syspath(path), 'rb') as f: + shutil.copyfileobj(f, tmp) + finally: + tmp.close() + + # Move the copied file into place. try: - shutil.copyfile(path, tmp) - os.replace(tmp, dest) + os.replace(tmp.name, syspath(dest)) tmp = None - os.remove(path) + os.remove(syspath(path)) except OSError as exc: raise FilesystemError(exc, 'move', (path, dest), traceback.format_exc()) diff --git a/docs/changelog.rst b/docs/changelog.rst index 4e1afb91a9..71ef9973be 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -28,6 +28,9 @@ Bug fixes: ``r128_album_gain`` fields was changed from integer to float to fix loss of precision due to truncation. :bug:`4169` +* Fix a regression in the previous release that caused a `TypeError` when + moving files across filesystems. + :bug:`4168` * :doc:`/plugins/convert`: Files are no longer converted when running import in ``--pretend`` mode. * :doc:`/plugins/convert`: Deleting the original files during conversion no