From 3c8eb35ac79972eb6af137e65a5a5303959f612a Mon Sep 17 00:00:00 2001 From: Thomas Fish Date: Wed, 16 Oct 2024 13:46:04 +0100 Subject: [PATCH 1/2] `redirect_output_to`: `flush()`, `fsync()`, and `close` before resetting stdout and stderr --- src/sim_recon/files/utils.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/sim_recon/files/utils.py b/src/sim_recon/files/utils.py index 409f11b..7dd01c6 100644 --- a/src/sim_recon/files/utils.py +++ b/src/sim_recon/files/utils.py @@ -146,15 +146,16 @@ def redirect_output_to(file_path: str | PathLike[str]) -> Generator[None, None, except Exception: logger.error("Failed to write output to log at %s", file_path, exc_info=True) finally: + if f is not None: + f.flush() + if f_fd is not None: + os.fsync(f_fd) + f.close() # Reset stdout and stderr file descriptors os.dup2(saved_stdout_fd, stdout_fd) os.dup2(saved_stderr_fd, stderr_fd) sys.stdout = saved_stdout sys.stderr = saved_sterr - if f_fd is not None: - os.fsync(f_fd) - if f is not None: - f.close() def combine_text_files( From 59241fb2e6b5b670ac22ee902da8fb4e85ef8684 Mon Sep 17 00:00:00 2001 From: Thomas Fish Date: Fri, 18 Oct 2024 12:25:12 +0100 Subject: [PATCH 2/2] `redirect_output_to`: open file with context manager --- src/sim_recon/files/utils.py | 46 +++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/src/sim_recon/files/utils.py b/src/sim_recon/files/utils.py index 7dd01c6..3aa408a 100644 --- a/src/sim_recon/files/utils.py +++ b/src/sim_recon/files/utils.py @@ -132,30 +132,32 @@ def redirect_output_to(file_path: str | PathLike[str]) -> Generator[None, None, saved_stdout_fd = os.dup(stdout_fd) saved_stderr_fd = os.dup(stderr_fd) saved_stdout = sys.stdout - saved_sterr = sys.stderr - f = None - f_fd = None + saved_stderr = sys.stderr try: - f = file_path.open("w+", buffering=1) - f_fd = f.fileno() - os.dup2(f_fd, stdout_fd) - os.dup2(f_fd, stderr_fd) - sys.stdout = f - sys.stderr = f - yield - except Exception: - logger.error("Failed to write output to log at %s", file_path, exc_info=True) - finally: - if f is not None: - f.flush() - if f_fd is not None: + with file_path.open("w+", buffering=1) as f: + f_fd = f.fileno() + try: + + os.dup2(f_fd, stdout_fd) + os.dup2(f_fd, stderr_fd) + sys.stdout = f + sys.stderr = f + yield + except Exception: + logger.error( + "Failed to redirect output to log at %s", file_path, exc_info=True + ) + finally: + sys.stdout.flush() + sys.stderr.flush() os.fsync(f_fd) - f.close() - # Reset stdout and stderr file descriptors - os.dup2(saved_stdout_fd, stdout_fd) - os.dup2(saved_stderr_fd, stderr_fd) - sys.stdout = saved_stdout - sys.stderr = saved_sterr + # Reset stdout and stderr file descriptors + os.dup2(saved_stdout_fd, stdout_fd) + os.dup2(saved_stderr_fd, stderr_fd) + sys.stdout = saved_stdout + sys.stderr = saved_stderr + except Exception: + logger.error("Failed to create log file %s", file_path) def combine_text_files(