From 73ed720b1a00070329aba4326c9e77518922982f Mon Sep 17 00:00:00 2001 From: Alex Jones Date: Fri, 30 Jan 2026 13:25:50 +0000 Subject: [PATCH 1/3] fix: Don't ignore input header message in EnlightenStatusPrinter Keep this as the default value and move it to a named constant for now to avoid repetition. This abstraction likely needs more work and this can be moved to a different location (the status table in general is quite entangled with the JobStatus), but that refactoring should be handled independent of this commit, which is just applying a fix. Signed-off-by: Alex Jones --- src/dvsim/scheduler.py | 4 +--- src/dvsim/utils/status_printer.py | 13 ++++++++----- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/dvsim/scheduler.py b/src/dvsim/scheduler.py index c2519799..c7c0e5e2 100644 --- a/src/dvsim/scheduler.py +++ b/src/dvsim/scheduler.py @@ -101,9 +101,7 @@ def __init__( # Print status periodically using an external status printer. self._status_printer = get_status_printer(interactive) - self._status_printer.print_header( - msg="Q: queued, D: dispatched, P: passed, F: failed, K: killed, T: total", - ) + self._status_printer.print_header() # Sets of items, split up by their current state. The sets are # disjoint and their union equals the keys of self.item_status. diff --git a/src/dvsim/utils/status_printer.py b/src/dvsim/utils/status_printer.py index 84f22dfb..747deb6d 100644 --- a/src/dvsim/utils/status_printer.py +++ b/src/dvsim/utils/status_printer.py @@ -11,6 +11,9 @@ from dvsim.logging import log +DEFAULT_HEADER = "Q: queued, D: dispatched, P: passed, F: failed, K: killed, T: total" +"""The default header to use for printing the status.""" + class StatusPrinter: """Dummy Status Printer class for interactive mode. @@ -23,7 +26,7 @@ class StatusPrinter: def __init__(self) -> None: """Initialise.""" - def print_header(self, msg: str) -> None: + def print_header(self) -> None: """Initialize / print the header bar. The header bar contains an introductory message such as the legend of @@ -84,13 +87,13 @@ def __init__(self) -> None: # than in the Scheduler class. self.target_done = {} - def print_header(self, msg: str) -> None: + def print_header(self) -> None: """Initialize / print the header bar. The header bar contains an introductory message such as the legend of what Q, D, ... mean. """ - log.info(self.header_fmt.format(hms="", target="legend", msg=msg)) + log.info(self.header_fmt.format(hms="", target="legend", msg=DEFAULT_HEADER)) def init_target(self, target: str, msg: str) -> None: """Initialize the status bar for each target.""" @@ -161,12 +164,12 @@ def __init__(self) -> None: self.status_header = None self.status_target = {} - def print_header(self, msg) -> None: + def print_header(self) -> None: self.status_header = self.manager.status_bar( status_format=self.header_fmt, hms="", target="legend", - msg="Q: queued, D: dispatched, P: passed, F: failed, K: killed, T: total", + msg=DEFAULT_HEADER, ) def init_target(self, target, msg) -> None: From 56f26446aeae5d2bad7706412040bf3ae18c7426 Mon Sep 17 00:00:00 2001 From: Alex Jones Date: Fri, 30 Jan 2026 13:28:17 +0000 Subject: [PATCH 2/3] fix: Handle EnlightenStatusPrinter early exit error If the EnlightenStatusPrinter is initialized and then `.exit()` is called without ever first calling `.print_header()`, then the `.exit()` method will attempt to call the `.close()` method on `None`, giving an `AttributeError`. Add a presence check to fix this. Signed-off-by: Alex Jones --- src/dvsim/utils/status_printer.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dvsim/utils/status_printer.py b/src/dvsim/utils/status_printer.py index 747deb6d..85909aae 100644 --- a/src/dvsim/utils/status_printer.py +++ b/src/dvsim/utils/status_printer.py @@ -198,7 +198,8 @@ def update_target(self, target, hms, msg, perc, running) -> None: def exit(self) -> None: """Do cleanup activities before exiting.""" - self.status_header.close() + if self.status_header is not None: + self.status_header.close() for target in self.status_target: self.status_target[target].close() From 699307b57e3d9e072e939a2b819a7fa5ed9dfda4 Mon Sep 17 00:00:00 2001 From: Alex Jones Date: Fri, 30 Jan 2026 13:37:10 +0000 Subject: [PATCH 3/3] fix: Explicitly stop EnlightenStatusPrinter manager Enlighten registers logic to (at least partially) reset the terminal using the `atexit` library and clean up, but we should explicitly close the Enlighten manager when we cleanup/exit the status printer to make sure that the terminal is fully restored to its normal working state. Signed-off-by: Alex Jones --- src/dvsim/utils/status_printer.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dvsim/utils/status_printer.py b/src/dvsim/utils/status_printer.py index 85909aae..db8f5ca7 100644 --- a/src/dvsim/utils/status_printer.py +++ b/src/dvsim/utils/status_printer.py @@ -202,6 +202,7 @@ def exit(self) -> None: self.status_header.close() for target in self.status_target: self.status_target[target].close() + self.manager.stop() def get_status_printer(interactive: bool) -> StatusPrinter: