Skip to content

Commit

Permalink
Merge pull request #4209 from beetbox/atomic-move-fix
Browse files Browse the repository at this point in the history
Improved fix for Unicode mistakes in atomic move
  • Loading branch information
sampsyo authored Jan 11, 2022
2 parents 28ceda1 + 1962223 commit a0587e0
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 13 deletions.
35 changes: 22 additions & 13 deletions beets/util/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down
3 changes: 3 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit a0587e0

Please sign in to comment.