From 9ddca412ad383cb04c272b4562bfb4d03d1232fd Mon Sep 17 00:00:00 2001 From: Tom Willemsen Date: Fri, 19 Dec 2025 13:20:21 +0000 Subject: [PATCH 1/2] Windows: add guards for some methods that don't work/exist on win32 --- src/fastcs/control_system.py | 6 ++++-- src/fastcs/logging/_logging.py | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/fastcs/control_system.py b/src/fastcs/control_system.py index fcd13ada0..87492ef4e 100644 --- a/src/fastcs/control_system.py +++ b/src/fastcs/control_system.py @@ -1,4 +1,5 @@ import asyncio +import os import signal from collections.abc import Coroutine, Sequence from functools import partial @@ -45,8 +46,9 @@ def __init__( def run(self, interactive: bool = True): serve = asyncio.ensure_future(self.serve(interactive=interactive)) - self._loop.add_signal_handler(signal.SIGINT, serve.cancel) - self._loop.add_signal_handler(signal.SIGTERM, serve.cancel) + if os.name != "nt": + self._loop.add_signal_handler(signal.SIGINT, serve.cancel) + self._loop.add_signal_handler(signal.SIGTERM, serve.cancel) self._loop.run_until_complete(serve) async def _run_initial_coros(self): diff --git a/src/fastcs/logging/_logging.py b/src/fastcs/logging/_logging.py index 2d54e2f01..a3f304c0a 100644 --- a/src/fastcs/logging/_logging.py +++ b/src/fastcs/logging/_logging.py @@ -1,5 +1,6 @@ import getpass import os +import sys from enum import StrEnum from logging import LogRecord from typing import TYPE_CHECKING, Any @@ -30,8 +31,9 @@ def _configure_logger( graylog_env_fields: GraylogEnvFields | None = None, ): logger.remove() + is_pytest_on_windows = "PYTEST_VERSION" in os.environ and os.name == "nt" logger.add( - sink=StdoutProxy(raw=True), # type: ignore + sink=sys.stdout if is_pytest_on_windows else StdoutProxy(raw=True), # type: ignore colorize=True, format=format_record, level=level or "INFO", From e4c48aec493145137d71e26204d6f3e60f7fb9ab Mon Sep 17 00:00:00 2001 From: Tom Willemsen Date: Fri, 26 Dec 2025 11:31:04 +0000 Subject: [PATCH 2/2] Catch exception in non-console context rather than detecting pytest Exception was also occuring in other non-console contexts, e.g. sphinx --- src/fastcs/logging/_logging.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/fastcs/logging/_logging.py b/src/fastcs/logging/_logging.py index a3f304c0a..6df00834a 100644 --- a/src/fastcs/logging/_logging.py +++ b/src/fastcs/logging/_logging.py @@ -31,9 +31,16 @@ def _configure_logger( graylog_env_fields: GraylogEnvFields | None = None, ): logger.remove() - is_pytest_on_windows = "PYTEST_VERSION" in os.environ and os.name == "nt" + + try: + out = StdoutProxy(raw=True) + except Exception: + # e.g. prompt_toolkit.output.win32.NoConsoleScreenBufferError on windows + # But it isn't exported from prompt_toolkit in a cross-platform way. + out = sys.stdout + logger.add( - sink=sys.stdout if is_pytest_on_windows else StdoutProxy(raw=True), # type: ignore + sink=out, # type: ignore colorize=True, format=format_record, level=level or "INFO",