From 5b9a0a337980717a9f6e489059e895464ef2d22b Mon Sep 17 00:00:00 2001 From: Jan Beran Date: Fri, 1 Mar 2024 18:58:18 +0100 Subject: [PATCH] fix(menuconfig): Prevent Access violation on Windows with Python 3.12 Closes https://github.com/espressif/esp-idf/issues/13232 --- tools/cmake/kconfig.cmake | 2 +- tools/kconfig_new/menuconfig_wrapper.py | 60 +++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 tools/kconfig_new/menuconfig_wrapper.py diff --git a/tools/cmake/kconfig.cmake b/tools/cmake/kconfig.cmake index ec8d290d61..25e03b2f71 100644 --- a/tools/cmake/kconfig.cmake +++ b/tools/cmake/kconfig.cmake @@ -199,7 +199,7 @@ function(__kconfig_generate_config sdkconfig sdkconfig_defaults) idf_build_set_property(SDKCONFIG_JSON_MENUS ${sdkconfig_json_menus}) idf_build_set_property(CONFIG_DIR ${config_dir}) - set(MENUCONFIG_CMD ${python} -m menuconfig) + set(MENUCONFIG_CMD ${python} ${idf_path}/tools/kconfig_new/menuconfig_wrapper.py) set(TERM_CHECK_CMD ${python} ${idf_path}/tools/check_term.py) # Generate the menuconfig target diff --git a/tools/kconfig_new/menuconfig_wrapper.py b/tools/kconfig_new/menuconfig_wrapper.py new file mode 100644 index 0000000000..9ae87c171e --- /dev/null +++ b/tools/kconfig_new/menuconfig_wrapper.py @@ -0,0 +1,60 @@ +# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 +import os +import sys +from typing import Any +from typing import Callable + +import menuconfig + +if os.name == 'nt': + import curses + + +def main() -> None: + if os.name == 'nt' and sys.version_info[:2] >= (3, 12): + curses.wrapper = _wrapper # type: ignore + menuconfig._main() + + +def _wrapper(func: Callable) -> Any: + # Using workaround to address windows-curses bug on Python 3.12 + # More info: https://github.com/zephyrproject-rtos/windows-curses/issues/50 + # This function is a copy of curses.wrapper with changes commented further in the code + if os.name == 'nt' and sys.version_info[:2] >= (3, 12): + stdscr = None + try: + import _curses + + # This crashes on Python 3.12 and needs to be commented out. + # It is not needed for the menuconfig to work, though. + # setupterm(term=_os.environ.get('TERM', 'unknown'), + # fd=_sys.__stdout__.fileno()) + stdscr = _curses.initscr() + for key, value in _curses.__dict__.items(): + if key[0:4] == 'ACS_' or key in ('LINES', 'COLS'): + setattr(curses, key, value) + + curses.noecho() + curses.cbreak() + + try: + curses.start_color() + except: # noqa: E722 + pass + + if stdscr is not None: + stdscr.keypad(True) + func(stdscr) + finally: + if stdscr is not None: + stdscr.keypad(False) + curses.echo() + curses.nocbreak() + return curses.endwin() + else: + return curses.wrapper(func) + + +if __name__ == '__main__': + main()