From fb4612778d44f251ed9a35ff2a59a9fae323bb56 Mon Sep 17 00:00:00 2001 From: Jakub Kocka Date: Thu, 17 Jul 2025 09:50:25 +0200 Subject: [PATCH] remove(tools): Dropping of virtualenv support --- tools/idf_tools.py | 162 ++++++++++++--------------------------------- 1 file changed, 43 insertions(+), 119 deletions(-) diff --git a/tools/idf_tools.py b/tools/idf_tools.py index e5c9c37c3c..91dc02f24c 100755 --- a/tools/idf_tools.py +++ b/tools/idf_tools.py @@ -2722,56 +2722,6 @@ def get_constraints(idf_version: str, online: bool = True) -> str: raise SystemExit(1) -def install_legacy_python_virtualenv(path: str) -> None: - """ - Checks if pip is installed (and installs it if not), - checks whether virtualenv is already installed (and in which version), - and finally creates virtual environment with python -m virtualenv . - """ - # Before creating the virtual environment, check if pip is installed. - try: - subprocess.check_call([sys.executable, '-m', 'pip', '--version']) - except subprocess.CalledProcessError: - fatal( - f"Python interpreter at {sys.executable} doesn't have pip installed. " - 'Please check the Getting Started Guides for the steps to install prerequisites for your OS.' - ) - raise SystemExit(1) - - virtualenv_installed_via_pip = False - try: - import virtualenv # noqa: F401 - except ImportError: - info('Installing virtualenv') - subprocess.check_call( - [sys.executable, '-m', 'pip', 'install', '--user', 'virtualenv'], stdout=sys.stdout, stderr=sys.stderr - ) - virtualenv_installed_via_pip = True - # since we just installed virtualenv via pip, we know that version is recent enough - # so the version check below is not necessary. - - with_seeder_option = True - if not virtualenv_installed_via_pip: - # virtualenv is already present in the system and may have been installed via OS package manager - # check the version to determine if we should add --seeder option - try: - major_ver = int(virtualenv.__version__.split('.')[0]) - if major_ver < 20: - warn(f'Virtualenv version {virtualenv.__version__} is old, please consider upgrading it') - with_seeder_option = False - except (ValueError, NameError, AttributeError, IndexError): - pass - - info(f'Creating a new Python environment using virtualenv in {path}') - virtualenv_options = ['--python', sys.executable] - if with_seeder_option: - virtualenv_options += ['--seeder', 'pip'] - - subprocess.check_call( - [sys.executable, '-m', 'virtualenv', *virtualenv_options, path], stdout=sys.stdout, stderr=sys.stderr - ) - - def action_install_python_env(args): # type: ignore """ (Re)installs python virtual environment. @@ -2782,16 +2732,6 @@ def action_install_python_env(args): # type: ignore reinstall = args.reinstall idf_python_env_path, _, virtualenv_python, idf_version = get_python_env_path() - nix_store = os.environ.get('NIX_STORE') - is_nix = nix_store is not None and sys.base_prefix.startswith(nix_store) and sys.prefix.startswith(nix_store) - - is_virtualenv = not is_nix and ( - hasattr(sys, 'real_prefix') or (hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix) - ) - if is_virtualenv and (not os.path.exists(idf_python_env_path) or reinstall): - fatal('This script was called from a virtual environment, can not create a virtual environment again') - raise SystemExit(1) - if os.path.exists(virtualenv_python): try: subprocess.check_call([virtualenv_python, '--version'], stdout=sys.stdout, stderr=sys.stderr) @@ -2821,69 +2761,53 @@ def action_install_python_env(args): # type: ignore if os.path.exists(virtualenv_python): check_python_venv_compatibility(idf_python_env_path, idf_version) else: - if ( - subprocess.run( - [sys.executable, '-m', 'venv', '-h'], check=False, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL - ).returncode - == 0 - ): - # venv available - virtualenv_options = [] - - info(f'Creating a new Python environment in {idf_python_env_path}') - - try: - environ_idf_python_env_path = os.environ['IDF_PYTHON_ENV_PATH'] - correct_env_path = environ_idf_python_env_path.endswith( - PYTHON_VENV_DIR_TEMPLATE.format(idf_version, PYTHON_VER_MAJOR_MINOR) - ) - if not correct_env_path and re.search( - PYTHON_VENV_DIR_TEMPLATE.format(r'\d+\.\d+', r'\d+\.\d+'), environ_idf_python_env_path - ): - warn( - f'IDF_PYTHON_ENV_PATH is set to {environ_idf_python_env_path} but it does not match ' - f'the detected {idf_version} ESP-IDF version and/or the used {PYTHON_VER_MAJOR_MINOR} ' - 'version of Python. If you have not set IDF_PYTHON_ENV_PATH intentionally then it is ' - 'recommended to re-run this script from a clean shell where an ESP-IDF environment is ' - 'not active.' - ) - - # Verify if IDF_PYTHON_ENV_PATH is a valid ESP-IDF Python virtual environment directory - # to decide if content should be removed - if os.path.exists(os.path.join(environ_idf_python_env_path, VENV_VER_FILE)) or re.search( - PYTHON_VENV_DIR_TEMPLATE.format(r'\d+\.\d+', r'\d+\.\d+'), environ_idf_python_env_path - ): - virtualenv_options.append('--clear') # delete environment if already exists - elif os.listdir(environ_idf_python_env_path): # show the message only if the directory is not empty - info( - f'IDF_PYTHON_ENV_PATH is set to {environ_idf_python_env_path}, ' - 'but it does not appear to be an ESP-IDF Python virtual environment directory. ' - 'Existing data in this folder will be preserved to prevent unintentional data loss.' - ) - - except KeyError: - # if IDF_PYTHON_ENV_PATH not defined then the above checks can be skipped - pass - - subprocess.check_call( - [sys.executable, '-m', 'venv', *virtualenv_options, idf_python_env_path], - stdout=sys.stdout, - stderr=sys.stderr, + virtualenv_options = [] + info(f'Creating a new Python environment in {idf_python_env_path}') + try: + environ_idf_python_env_path = os.environ['IDF_PYTHON_ENV_PATH'] + correct_env_path = environ_idf_python_env_path.endswith( + PYTHON_VENV_DIR_TEMPLATE.format(idf_version, PYTHON_VER_MAJOR_MINOR) ) - - try: - with open(os.path.join(idf_python_env_path, VENV_VER_FILE), 'w', encoding='utf-8') as f: - f.write(idf_version) - except OSError: + if not correct_env_path and re.search( + PYTHON_VENV_DIR_TEMPLATE.format(r'\d+\.\d+', r'\d+\.\d+'), environ_idf_python_env_path + ): warn( - 'The following issue occurred while generating the ' - 'ESP-IDF version file in the Python environment: {e}. ' - '(Diagnostic information. It can be ignored.)' + f'IDF_PYTHON_ENV_PATH is set to {environ_idf_python_env_path} but it does not match ' + f'the detected {idf_version} ESP-IDF version and/or the used {PYTHON_VER_MAJOR_MINOR} ' + 'version of Python. If you have not set IDF_PYTHON_ENV_PATH intentionally then it is ' + 'recommended to re-run this script from a clean shell where an ESP-IDF environment is ' + 'not active.' + ) + # Verify if IDF_PYTHON_ENV_PATH is a valid ESP-IDF Python virtual environment directory + # to decide if content should be removed + if os.path.exists(os.path.join(environ_idf_python_env_path, VENV_VER_FILE)) or re.search( + PYTHON_VENV_DIR_TEMPLATE.format(r'\d+\.\d+', r'\d+\.\d+'), environ_idf_python_env_path + ): + virtualenv_options.append('--clear') # delete environment if already exists + elif os.listdir(environ_idf_python_env_path): # show the message only if the directory is not empty + info( + f'IDF_PYTHON_ENV_PATH is set to {environ_idf_python_env_path}, ' + 'but it does not appear to be an ESP-IDF Python virtual environment directory. ' + 'Existing data in this folder will be preserved to prevent unintentional data loss.' ) - else: - # The embeddable Python for Windows doesn't have the built-in venv module - install_legacy_python_virtualenv(idf_python_env_path) + except KeyError: + # if IDF_PYTHON_ENV_PATH not defined then the above checks can be skipped + pass + subprocess.check_call( + [sys.executable, '-m', 'venv', *virtualenv_options, idf_python_env_path], + stdout=sys.stdout, + stderr=sys.stderr, + ) + try: + with open(os.path.join(idf_python_env_path, VENV_VER_FILE), 'w', encoding='utf-8') as f: + f.write(idf_version) + except OSError: + warn( + 'The following issue occurred while generating the ' + 'ESP-IDF version file in the Python environment: {e}. ' + '(Diagnostic information. It can be ignored.)' + ) env_copy = os.environ.copy() # Enforce disabling possible pip 'user' option to prevent installation error with virtual environment