From d75201a873a413d73f12748e5710f000e9f727da Mon Sep 17 00:00:00 2001 From: Paul Wrubel Date: Thu, 26 Aug 2021 21:27:20 -0500 Subject: [PATCH] Use `os.replace` where applicable (#793) When using ```py os.remove(encodeFilename(filename)) os.rename(encodeFilename(temp_filename), encodeFilename(filename)) ``` the `os.remove` need not be atomic and so can be executed arbitrarily compared to the immediately following rename call. It is better to use `os.replace` instead Authored by: paulwrubel --- .gitignore | 2 ++ yt_dlp/downloader/common.py | 7 ++----- yt_dlp/postprocessor/embedthumbnail.py | 3 +-- yt_dlp/postprocessor/ffmpeg.py | 13 ++++--------- yt_dlp/postprocessor/sponskrub.py | 3 +-- 5 files changed, 10 insertions(+), 18 deletions(-) diff --git a/.gitignore b/.gitignore index 7ed34448a..619d6ba98 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,8 @@ cookies.txt *.wav *.ape *.mkv +*.flac +*.avi *.swf *.part *.part-* diff --git a/yt_dlp/downloader/common.py b/yt_dlp/downloader/common.py index f5f6393a6..ce914bd4a 100644 --- a/yt_dlp/downloader/common.py +++ b/yt_dlp/downloader/common.py @@ -207,12 +207,9 @@ def try_rename(self, old_filename, new_filename): if old_filename == new_filename: return try: - if self.params.get('overwrites', False): - if os.path.isfile(encodeFilename(new_filename)): - os.remove(encodeFilename(new_filename)) - os.rename(encodeFilename(old_filename), encodeFilename(new_filename)) + os.replace(old_filename, new_filename) except (IOError, OSError) as err: - self.report_error('unable to rename file: %s' % error_to_compat_str(err)) + self.report_error(f'unable to rename file: {err}') def try_utime(self, filename, last_modified_hdr): """Try to set the last-modified time of the given file.""" diff --git a/yt_dlp/postprocessor/embedthumbnail.py b/yt_dlp/postprocessor/embedthumbnail.py index 7008f4d4d..3139a6338 100644 --- a/yt_dlp/postprocessor/embedthumbnail.py +++ b/yt_dlp/postprocessor/embedthumbnail.py @@ -222,8 +222,7 @@ def run(self, info): raise EmbedThumbnailPPError('Supported filetypes for thumbnail embedding are: mp3, mkv/mka, ogg/opus/flac, m4a/mp4/mov') if success and temp_filename != filename: - os.remove(encodeFilename(filename)) - os.rename(encodeFilename(temp_filename), encodeFilename(filename)) + os.replace(temp_filename, filename) self.try_utime(filename, mtime, mtime) diff --git a/yt_dlp/postprocessor/ffmpeg.py b/yt_dlp/postprocessor/ffmpeg.py index be6cc9f09..b66a0b445 100644 --- a/yt_dlp/postprocessor/ffmpeg.py +++ b/yt_dlp/postprocessor/ffmpeg.py @@ -520,8 +520,7 @@ def run(self, information): temp_filename = prepend_extension(filename, 'temp') self.to_screen('Embedding subtitles in "%s"' % filename) self.run_ffmpeg_multiple_files(input_files, temp_filename, opts) - os.remove(encodeFilename(filename)) - os.rename(encodeFilename(temp_filename), encodeFilename(filename)) + os.replace(temp_filename, filename) files_to_delete = [] if self._already_have_subtitle else sub_filenames return files_to_delete, information @@ -628,8 +627,7 @@ def ffmpeg_escape(text): itertools.chain(self._options(info['ext']), *options)) if chapters: os.remove(metadata_filename) - os.remove(encodeFilename(filename)) - os.rename(encodeFilename(temp_filename), encodeFilename(filename)) + os.replace(temp_filename, filename) return [], info @@ -673,8 +671,7 @@ def _fixup(self, msg, filename, options): self.to_screen(f'{msg} of "{filename}"') self.run_ffmpeg(filename, temp_filename, options) - os.remove(encodeFilename(filename)) - os.rename(encodeFilename(temp_filename), encodeFilename(filename)) + os.replace(temp_filename, filename) class FFmpegFixupStretchedPP(FFmpegFixupPostProcessor): @@ -866,9 +863,7 @@ def fixup_webp(self, info, idx=-1): if thumbnail_ext != 'webp' and self.is_webp(thumbnail_filename): self.to_screen('Correcting thumbnail "%s" extension to webp' % thumbnail_filename) webp_filename = replace_extension(thumbnail_filename, 'webp') - if os.path.exists(webp_filename): - os.remove(webp_filename) - os.rename(encodeFilename(thumbnail_filename), encodeFilename(webp_filename)) + os.replace(thumbnail_filename, webp_filename) info['thumbnails'][idx]['filepath'] = webp_filename info['__files_to_move'][webp_filename] = replace_extension( info['__files_to_move'].pop(thumbnail_filename), 'webp') diff --git a/yt_dlp/postprocessor/sponskrub.py b/yt_dlp/postprocessor/sponskrub.py index 73b6b4a20..588f0ae12 100644 --- a/yt_dlp/postprocessor/sponskrub.py +++ b/yt_dlp/postprocessor/sponskrub.py @@ -84,8 +84,7 @@ def run(self, information): stdout = process_communicate_or_kill(p)[0] if p.returncode == 0: - os.remove(encodeFilename(filename)) - os.rename(encodeFilename(temp_filename), encodeFilename(filename)) + os.replace(temp_filename, filename) self.to_screen('Sponsor sections have been %s' % ('removed' if self.cutout else 'marked')) elif p.returncode == 3: self.to_screen('No segments in the SponsorBlock database')