From aa93e61e4830e9f437bcc309a1551d298f83a72a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 26 Feb 2026 16:52:50 +0000 Subject: [PATCH] Fix func worker segfault on Python 3.13 by redirecting worker to Python 3.12 The Azure Functions Python worker crashes with SIGSEGV (exit code 139) on Python 3.13 due to protobuf C extension (google._upb) compatibility issues. When the test runner uses Python >=3.13, the conftest now automatically finds a compatible Python 3.10-3.12 and sets languageWorkers__python__defaultExecutablePath so the func host uses it for the worker process. The CI setup action also ensures Python 3.12 is available on the runner, falling back to uv python install if the system doesn't have it. Co-authored-by: larohra <41490930+larohra@users.noreply.github.com> --- .../action.yml | 15 ++++++++ .../tests/integration_tests/conftest.py | 35 +++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/.github/actions/azure-functions-integration-setup/action.yml b/.github/actions/azure-functions-integration-setup/action.yml index 28c1c6cd1d..99b8207a82 100644 --- a/.github/actions/azure-functions-integration-setup/action.yml +++ b/.github/actions/azure-functions-integration-setup/action.yml @@ -46,3 +46,18 @@ runs: echo "Installing Azure Functions Core Tools" npm install -g azure-functions-core-tools@4 --unsafe-perm true func --version + - name: Ensure Python 3.12 is available for Azure Functions worker + shell: bash + run: | + # The Azure Functions Python worker may segfault on Python >=3.13 + # (protobuf C extension crash). Ensure a compatible Python is + # available so the conftest can redirect the worker to it. + if ! python3.12 --version 2>/dev/null; then + echo "Python 3.12 not found on system, installing via uv..." + uv python install 3.12 + FUNC_WORKER_PYTHON="$(uv python find 3.12)" + echo "FUNC_WORKER_PYTHON=${FUNC_WORKER_PYTHON}" >> "$GITHUB_ENV" + echo "Installed Python 3.12 at ${FUNC_WORKER_PYTHON}" + else + echo "System Python 3.12 found: $(which python3.12)" + fi diff --git a/python/packages/azurefunctions/tests/integration_tests/conftest.py b/python/packages/azurefunctions/tests/integration_tests/conftest.py index 56eb8d3a5f..acfe59c313 100644 --- a/python/packages/azurefunctions/tests/integration_tests/conftest.py +++ b/python/packages/azurefunctions/tests/integration_tests/conftest.py @@ -350,6 +350,34 @@ def _load_and_validate_env() -> None: ) +def _find_func_worker_python() -> str | None: + """Find a Python 3.10-3.12 executable for the Azure Functions worker. + + The Azure Functions Core Tools worker may segfault on Python >=3.13 due to + protobuf/grpcio C extension compatibility issues (``google._upb`` crash). + This returns a path to a compatible Python interpreter so the function host + can use it instead of the default (which is the test runner's Python). + + Returns ``None`` when the current interpreter is already compatible or no + alternative can be found. + """ + if sys.version_info < (3, 13): + return None # Current Python is compatible; no override needed. + + # Check for an explicit override first (e.g. set by CI). + explicit = os.environ.get("FUNC_WORKER_PYTHON", "").strip() + if explicit and Path(explicit).is_file(): + return explicit + + # Try versioned system executables (python3.12, python3.11, python3.10). + for minor in range(12, 9, -1): + path = shutil.which(f"python3.{minor}") + if path: + return path + + return None + + def _start_function_app(sample_path: Path, port: int) -> subprocess.Popen[Any]: """Start a function app in the specified sample directory. @@ -361,6 +389,13 @@ def _start_function_app(sample_path: Path, port: int) -> subprocess.Popen[Any]: # use the task hub name to separate orchestration state. env["TASKHUB_NAME"] = f"test{uuid.uuid4().hex[:8]}" + # The Azure Functions Python worker may crash on Python >=3.13 with a + # SIGSEGV in the protobuf C extension (google._upb). Point the worker at + # a compatible Python when one is available. + worker_python = _find_func_worker_python() + if worker_python: + env["languageWorkers__python__defaultExecutablePath"] = worker_python + # On Windows, use CREATE_NEW_PROCESS_GROUP to allow proper termination # shell=True only on Windows to handle PATH resolution if sys.platform == "win32":