diff --git a/homeassistant/helpers/importlib.py b/homeassistant/helpers/importlib.py index 00af75f6d8e..98c75939084 100644 --- a/homeassistant/helpers/importlib.py +++ b/homeassistant/helpers/importlib.py @@ -30,11 +30,9 @@ async def async_import_module(hass: HomeAssistant, name: str) -> ModuleType: if module := cache.get(name): return module - failure_cache: dict[str, BaseException] = hass.data.setdefault( - DATA_IMPORT_FAILURES, {} - ) - if exception := failure_cache.get(name): - raise exception + failure_cache: dict[str, bool] = hass.data.setdefault(DATA_IMPORT_FAILURES, {}) + if name in failure_cache: + raise ModuleNotFoundError(f"{name} not found", name=name) import_futures: dict[str, asyncio.Future[ModuleType]] import_futures = hass.data.setdefault(DATA_IMPORT_FUTURES, {}) @@ -51,7 +49,8 @@ async def async_import_module(hass: HomeAssistant, name: str) -> ModuleType: module = await hass.async_add_import_executor_job(_get_module, cache, name) import_future.set_result(module) except BaseException as ex: - failure_cache[name] = ex + if isinstance(ex, ModuleNotFoundError): + failure_cache[name] = True import_future.set_exception(ex) with suppress(BaseException): # Set the exception retrieved flag on the future since diff --git a/tests/helpers/test_importlib.py b/tests/helpers/test_importlib.py index 5683dd5cf94..5c9686233f9 100644 --- a/tests/helpers/test_importlib.py +++ b/tests/helpers/test_importlib.py @@ -41,16 +41,40 @@ async def test_async_import_module_failures(hass: HomeAssistant) -> None: with ( patch( "homeassistant.helpers.importlib.importlib.import_module", - side_effect=ImportError, + side_effect=ValueError, ), - pytest.raises(ImportError), + pytest.raises(ValueError), + ): + await importlib.async_import_module(hass, "test.module") + + mock_module = MockModule() + # The failure should be not be cached + with ( + patch( + "homeassistant.helpers.importlib.importlib.import_module", + return_value=mock_module, + ), + ): + assert await importlib.async_import_module(hass, "test.module") is mock_module + + +async def test_async_import_module_failure_caches_module_not_found( + hass: HomeAssistant, +) -> None: + """Test importing a module caches ModuleNotFound.""" + with ( + patch( + "homeassistant.helpers.importlib.importlib.import_module", + side_effect=ModuleNotFoundError, + ), + pytest.raises(ModuleNotFoundError), ): await importlib.async_import_module(hass, "test.module") mock_module = MockModule() # The failure should be cached with ( - pytest.raises(ImportError), + pytest.raises(ModuleNotFoundError), patch( "homeassistant.helpers.importlib.importlib.import_module", return_value=mock_module,