From 07adddd1717d27bbc93f71d749dd57debf61a3fe Mon Sep 17 00:00:00 2001 From: Amandeep vishwkarma Date: Sat, 16 May 2026 10:21:40 +0530 Subject: [PATCH] Fix optional orjson/ujson import breaking fastapi.responses Catches ImportError instead of ModuleNotFoundError to handle cases where the package exists but its C-extension fails to load. --- fastapi/responses.py | 4 ++-- tests/test_responses_optional_imports.py | 26 ++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 tests/test_responses_optional_imports.py diff --git a/fastapi/responses.py b/fastapi/responses.py index 29df4b7a61..0c9caa4d04 100644 --- a/fastapi/responses.py +++ b/fastapi/responses.py @@ -26,13 +26,13 @@ class _OrjsonModule(Protocol): try: ujson = cast(_UjsonModule, importlib.import_module("ujson")) -except ModuleNotFoundError: # pragma: nocover +except ImportError: # pragma: nocover ujson = None # type: ignore[assignment] try: orjson = cast(_OrjsonModule, importlib.import_module("orjson")) -except ModuleNotFoundError: # pragma: nocover +except ImportError: # pragma: nocover orjson = None # type: ignore[assignment] diff --git a/tests/test_responses_optional_imports.py b/tests/test_responses_optional_imports.py new file mode 100644 index 0000000000..c08d18c38e --- /dev/null +++ b/tests/test_responses_optional_imports.py @@ -0,0 +1,26 @@ +import importlib +import sys +from typing import Any + +import pytest + +def test_optional_imports_broken_installation(monkeypatch: pytest.MonkeyPatch) -> None: + """ + Test that an ImportError during the import of an optional JSON library + (like orjson or ujson) does not crash the entire fastapi.responses module. + """ + real_import_module = importlib.import_module + + def fake_import_module(name: str, package: str | None = None) -> Any: + if name in ("ujson", "orjson"): + raise ImportError(f"simulated binary/load failure for {name}") + return real_import_module(name, package) + + monkeypatch.setattr(importlib, "import_module", fake_import_module) + + # Force a reload to ensure the module initialization runs with our monkeypatch + if "fastapi.responses" in sys.modules: + del sys.modules["fastapi.responses"] + + # This should not raise an ImportError + import fastapi.responses # noqa: F401