Azure / Azure/azure-functions-python-worker

[Python 3.14 proxy worker] Missing sys.modules["__main__"] breaks multiprocessing spawn

オープン
#1,903 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る
主要言語
Python
スター
357
フォーク
116
平均マージ
32分
マージ済み PR(30日)
1

説明

### Description

The Azure Functions Python 3.14 proxy worker removes `__main__` from
`sys.modules` before invoking application code.

As a result, Python's standard `multiprocessing` spawn context fails during
`Process.start()`, before the child process or its target function begins
executing.

This is not specific to any third-party package. The minimal reproduction uses
only `azure-functions` and the Python standard library.

### Environment

- Azure Functions Python runtime: 3.14
- Python: 3.14.6
- Azure Functions Core Tools: 4.12.0
- Functions runtime: 4.1048.200.26180
- Programming model: Python v2
- `azure-functions` application package: 2.2.0
- Reproduced locally inside the Functions worker
- The same failure was observed after deploying the application to Azure Functions on Python 3.14

The same application code worked on the Python 3.12 Functions runtime.

### Minimal reproduction

```python
import multiprocessing
import sys

import azure.functions as func

app = func.FunctionApp()

def child_process() -> None:
return None

@app.route(route="multiprocessing-repro")
def multiprocessing_repro(req: func.HttpRequest) -> func.HttpResponse:
main_present = "__main__" in sys.modules

context = multiprocessing.get_context("spawn")
process = context.Process(target=child_process)
process.start()
process.join()

return func.HttpResponse(
f"__main__ present: {main_present}; exit code: {process.exitcode}"
)
```

Start the application using Core Tools with Python 3.14 and invoke
`/api/multiprocessing-repro`.

### Actual behavior

`"__main__" in sys.modules` is false during the function invocation, and
`Process.start()` raises:

```text
Traceback (most recent call last):
File ".../multiprocessing/process.py", line 121, in start
self._popen = self._Popen(self)
File ".../multiprocessing/context.py", line 289, in _Popen
return Popen(process_obj)
File ".../multiprocessing/popen_spawn_posix.py", line 32, in __init__
super().__init__(process_obj)
File ".../multiprocessing/popen_fork.py", line 19, in __init__
self._launch(process_obj)
File ".../multiprocessing/popen_spawn_posix.py", line 42, in _launch
prep_data = spawn.get_preparation_data(process_obj._name)
File ".../multiprocessing/spawn.py", line 164, in get_preparation_data
main_module = sys.modules["__main__"]
KeyError: "__main__"
```

The failure occurs before the child process starts.

### Expected behavior

The Functions worker should retain a valid `__main__` module, or otherwise
initialize the application environment so that standard-library
`multiprocessing` spawn works inside a function invocation.

### Investigation

The Python 3.14 worker uses `proxy_worker`. Its dependency cleanup appears to
remove modules from `sys.modules` based on their file location. It excludes
modules whose names begin with `proxy_worker`, but does not appear to exclude
`__main__`.

That appears to leave the invocation environment without the module required
by `multiprocessing.spawn.get_preparation_data()`.

Launching an explicit Python subprocess with an importable module works in the
same Functions-host process, confirming that the failure is specifically in
the `multiprocessing` spawn preparation path.

### Impact

Any application or dependency that uses the standard-library spawn context can
fail under the Python 3.14 Functions worker. In our application this prevented
all isolated document conversions from starting, regardless of document type.

### Related issue

Related historical issue: #1094 reported the same missing-`__main__` worker
condition on Python 3.9 through a different caller.

This report concerns the Python 3.14 proxy worker and reproduces through:

```python
multiprocessing.get_context("spawn").Process(...).start()
```

It is therefore related behavior, but not the same caller or worker
implementation.

コントリビューションガイド

コントリビューションガイドを開く

調査の方向性

まず、調査で説明されている Python 3.14 の proxy_worker の依存関係クリーンアップパスを特定し、最小限の multiprocessing spawn 例で失敗を再現します。__main__ が削除される理由を追跡し、その後、worker のクリーンアップ動作を壊すことなく、再現コードで子プロセスを正常に start して join できることを確認します。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
azure, python
領域
backend, cloud
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
静か
明瞭さ
おおむね明確
初心者へのやさしさ
55/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。