Azure / Azure/azure-functions-python-worker

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

Offen
#1,903 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
Vorherrschende Sprache
Python
Sterne
357
Forks
116
Ø Merge
32 Min.
Gemergte PRs (30 T.)
1

Beschreibung

### 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.

Beitragsleitfaden

Beitragsleitfaden öffnen

Rechercherichtung

Beginne damit, den in der Untersuchung beschriebenen Python-3.14-Pfad zur Bereinigung der proxy_worker-Abhängigkeit zu finden, und reproduziere den Fehler mit dem minimalen multiprocessing-spawn-Beispiel. Verfolge, warum __main__ entfernt wird, und überprüfe anschließend, dass die Reproduktion den Kindprozess erfolgreich starten und mit join abwarten kann, ohne das Bereinigungsverhalten des Workers zu beeinträchtigen.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
azure, python
Bereich
backend, cloud
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Ruhig
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
55/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.