From dcea3ba062d3bc483c063861198955558a1772bd Mon Sep 17 00:00:00 2001 From: cyphercodes Date: Sat, 16 May 2026 06:16:20 +0300 Subject: [PATCH] Handle ImportError for optional JSON response imports --- fastapi/responses.py | 4 ++-- tests/test_responses_import.py | 40 ++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 tests/test_responses_import.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_import.py b/tests/test_responses_import.py new file mode 100644 index 0000000000..45c035f252 --- /dev/null +++ b/tests/test_responses_import.py @@ -0,0 +1,40 @@ +import subprocess +import sys +import textwrap +from pathlib import Path + +import pytest + + +REPO_ROOT = Path(__file__).resolve().parents[1] + + +@pytest.mark.parametrize("optional_module_name", ("ujson", "orjson")) +def test_responses_imports_when_optional_json_import_raises_import_error( + optional_module_name: str, +) -> None: + code = textwrap.dedent( + f""" + import importlib + + real_import_module = importlib.import_module + + def fake_import_module(name, package=None): + if name == {optional_module_name!r}: + raise ImportError("simulated optional dependency load failure") + return real_import_module(name, package) + + importlib.import_module = fake_import_module + + import fastapi.responses as responses + + assert getattr(responses, {optional_module_name!r}) is None + """ + ) + result = subprocess.run( + [sys.executable, "-c", code], + capture_output=True, + cwd=REPO_ROOT, + text=True, + ) + assert result.returncode == 0, result.stderr + result.stdout