aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--yt_dlp/utils.py23
1 files changed, 19 insertions, 4 deletions
diff --git a/yt_dlp/utils.py b/yt_dlp/utils.py
index 87dd04e23..66c3da4c8 100644
--- a/yt_dlp/utils.py
+++ b/yt_dlp/utils.py
@@ -2222,10 +2222,23 @@ class locked_file(object):
locked = False
def __init__(self, filename, mode, block=True, encoding=None):
- assert mode in {'r', 'rb', 'a', 'ab', 'w', 'wb'}
- self.f = open(filename, mode, encoding=encoding)
- self.mode = mode
- self.block = block
+ if mode not in {'r', 'rb', 'a', 'ab', 'w', 'wb'}:
+ raise NotImplementedError(mode)
+ self.mode, self.block = mode, block
+
+ writable = any(f in mode for f in 'wax+')
+ readable = any(f in mode for f in 'r+')
+ flags = functools.reduce(operator.ior, (
+ getattr(os, 'O_CLOEXEC', 0), # UNIX only
+ getattr(os, 'O_BINARY', 0), # Windows only
+ getattr(os, 'O_NOINHERIT', 0), # Windows only
+ os.O_CREAT if writable else 0, # O_TRUNC only after locking
+ os.O_APPEND if 'a' in mode else 0,
+ os.O_EXCL if 'x' in mode else 0,
+ os.O_RDONLY if not writable else os.O_RDWR if readable else os.O_WRONLY,
+ ))
+
+ self.f = os.fdopen(os.open(filename, flags), mode, encoding=encoding)
def __enter__(self):
exclusive = 'r' not in self.mode
@@ -2235,6 +2248,8 @@ class locked_file(object):
except IOError:
self.f.close()
raise
+ if 'w' in self.mode:
+ self.f.truncate()
return self
def unlock(self):