From 0dc3da6dce1dd5007d77acbe06118263884f5512 Mon Sep 17 00:00:00 2001 From: Roland Dobai Date: Thu, 15 Apr 2021 18:51:25 +0200 Subject: [PATCH] tools: Fix ANSI color converter on Windows Fix a regression of b77addea2fc44d1a336070e156d1c4deb50f752e: The ANSI color converter returns a class on Windows instead of an object so its methods won't be callable and will result in a not so helpful error message: "idf_monitor failed with exit code 120" --- tools/idf_monitor.py | 8 +++---- ...r_convertor.py => ansi_color_converter.py} | 22 ++++++++++++++----- 2 files changed, 20 insertions(+), 10 deletions(-) rename tools/idf_monitor_base/{ansi_color_convertor.py => ansi_color_converter.py} (89%) diff --git a/tools/idf_monitor.py b/tools/idf_monitor.py index fdf4295c6e..e1a9164b5c 100755 --- a/tools/idf_monitor.py +++ b/tools/idf_monitor.py @@ -73,7 +73,7 @@ import tempfile import serial import serial.tools.list_ports # Windows console stuff -from idf_monitor_base.ansi_color_convertor import ANSIColorConverter +from idf_monitor_base.ansi_color_converter import get_converter key_description = miniterm.key_description @@ -101,9 +101,9 @@ class Monitor(object): self.console = miniterm.Console() self.enable_address_decoding = enable_address_decoding - sys.stderr = ANSIColorConverter(sys.stderr, decode_output=True) - self.console.output = ANSIColorConverter(self.console.output) - self.console.byte_output = ANSIColorConverter(self.console.byte_output) + sys.stderr = get_converter(sys.stderr, decode_output=True) + self.console.output = get_converter(self.console.output) + self.console.byte_output = get_converter(self.console.byte_output) socket_mode = serial_instance.port.startswith( 'socket://') # testing hook - data from serial can make exit the monitor diff --git a/tools/idf_monitor_base/ansi_color_convertor.py b/tools/idf_monitor_base/ansi_color_converter.py similarity index 89% rename from tools/idf_monitor_base/ansi_color_convertor.py rename to tools/idf_monitor_base/ansi_color_converter.py index b465773afb..906db777d5 100644 --- a/tools/idf_monitor_base/ansi_color_convertor.py +++ b/tools/idf_monitor_base/ansi_color_converter.py @@ -17,7 +17,11 @@ import os import re import sys from io import TextIOBase -from typing import Union + +try: + from typing import Optional, Union +except ImportError: + pass from .output_helpers import ANSI_NORMAL @@ -39,6 +43,17 @@ if os.name == 'nt': SetConsoleTextAttribute = ctypes.windll.kernel32.SetConsoleTextAttribute # type: ignore +def get_converter(orig_output_method=None, decode_output=False): + # type: (Optional[TextIOBase], bool) -> Union[ANSIColorConverter, Optional[TextIOBase]] + """ + Returns an ANSIColorConverter on Windows and the original output method (orig_output_method) on other platforms. + The ANSIColorConverter with decode_output=True will decode the bytes before passing them to the output. + """ + if os.name == 'nt': + return ANSIColorConverter(orig_output_method, decode_output) + return orig_output_method + + class ANSIColorConverter(object): """Class to wrap a file-like output stream, intercept ANSI color codes, and convert them into calls to Windows SetConsoleTextAttribute. @@ -50,11 +65,6 @@ class ANSIColorConverter(object): least-bad working solution, as winpty doesn't support any "passthrough" mode for raw output. """ - def __new__(cls, output=None, decode_output=False): # type: ignore # noqa - if os.name == 'nt': - return cls - return output - def __init__(self, output=None, decode_output=False): # type: (TextIOBase, bool) -> None self.output = output