Skip to content

feat: add python-disable-gunicorn flag#10708

Draft
IzaakGough wants to merge 7 commits into
mainfrom
@invertase/feat-add-python-disable-gunicorn-flag
Draft

feat: add python-disable-gunicorn flag#10708
IzaakGough wants to merge 7 commits into
mainfrom
@invertase/feat-add-python-disable-gunicorn-flag

Conversation

@IzaakGough

@IzaakGough IzaakGough commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Fixes #6628

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a --python-disable-gunicorn option to the Firebase emulators, allowing Python Functions to run using the Flask server in non-debug mode instead of gunicorn to prevent fork-safety crashes on macOS. This is implemented by dynamically injecting a sitecustomize.py shim via PYTHONPATH to intercept and block gunicorn imports. The feedback recommends improving the Python import hook's robustness by using *args and **kwargs to support varying signatures, and registering a process exit hook to clean up the temporary directory created for the shim to prevent resource leaks.

Comment on lines +88 to +91
def _firebase_import_without_gunicorn(name, globals=None, locals=None, fromlist=(), level=0):
if name == "functions_framework._http.gunicorn":
raise ImportError("Gunicorn disabled for local Firebase Functions emulator")
return _original_import(name, globals, locals, fromlist, level)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The _firebase_import_without_gunicorn hook currently uses a fixed signature (name, globals=None, locals=None, fromlist=(), level=0). To ensure maximum compatibility across different Python versions, alternative interpreters, or third-party packages that might call __import__ with different positional/keyword arguments, it is more robust to use *args and **kwargs and extract the name argument dynamically.

Suggested change
def _firebase_import_without_gunicorn(name, globals=None, locals=None, fromlist=(), level=0):
if name == "functions_framework._http.gunicorn":
raise ImportError("Gunicorn disabled for local Firebase Functions emulator")
return _original_import(name, globals, locals, fromlist, level)
def _firebase_import_without_gunicorn(*args, **kwargs):
name = args[0] if args else kwargs.get("name")
if name == "functions_framework._http.gunicorn":
raise ImportError("Gunicorn disabled for local Firebase Functions emulator")
return _original_import(*args, **kwargs)

Comment thread src/emulator/functionsEmulator.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Emulator error Error: socket hang up

2 participants