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>
This commit is contained in:
copilot-swe-agent[bot]
2026-02-26 16:52:50 +00:00
Unverified
parent 3826e504be
commit aa93e61e48
2 changed files with 50 additions and 0 deletions
@@ -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":