diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py --- a/Lib/importlib/_bootstrap.py +++ b/Lib/importlib/_bootstrap.py @@ -84,24 +84,30 @@ def _write_atomic(path, data): """Best-effort function to write data to a path atomically. Be prepared to handle a FileExistsError if concurrent writing of the temporary file is attempted.""" - if not sys.platform.startswith('win'): + if sys.platform.startswith('win'): + rename_to = None + else: # On POSIX-like platforms, renaming is atomic - path_tmp = path + '.tmp' - try: - fd = _os.open(path_tmp, _os.O_EXCL | _os.O_CREAT | _os.O_WRONLY) - with _io.FileIO(fd, 'wb') as file: - file.write(data) - _os.rename(path_tmp, path) - except OSError: - try: - _os.unlink(path_tmp) - except OSError: - pass - raise - else: - with _io.FileIO(path, 'wb') as file: + rename_to = path + + try: + _os.unlink(path) + except OSError: + pass + + try: + flags = _os.O_EXCL | _os.O_CREAT | _os.O_WRONLY | _os.O_TRUNC + fd = _os.open(path, flags) + except OSError: + return + + try: + with _io.FileIO(fd, 'wb') as file: file.write(data) - + if rename_to is not None: + _os.rename(path, rename_to) + except OSError: + _os.unlink(path) def _wrap(new, old): """Simple substitute for functools.wraps."""