From 32974fda485b0ad4fc019d2d7018f4b90766f0a0 Mon Sep 17 00:00:00 2001 From: dangotbanned <125183946+dangotbanned@users.noreply.github.com> Date: Sun, 14 Sep 2025 12:17:35 +0000 Subject: [PATCH] chore: Make `Implementation.UNKNOWN._backend_version()` safe Closes #3132 Related #2786 --- narwhals/_utils.py | 5 ++--- tests/dependencies/imports_test.py | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/narwhals/_utils.py b/narwhals/_utils.py index 8f0ed9b4f8..f67c261c11 100644 --- a/narwhals/_utils.py +++ b/narwhals/_utils.py @@ -629,9 +629,8 @@ def _import_native_namespace(module_name: str) -> ModuleType: def backend_version(implementation: Implementation, /) -> tuple[int, ...]: if not isinstance(implementation, Implementation): assert_never(implementation) - if implementation is Implementation.UNKNOWN: # pragma: no cover - msg = "Cannot return backend version from UNKNOWN Implementation" - raise AssertionError(msg) + if implementation is Implementation.UNKNOWN: + return (0, 0, 0) into_version: ModuleType | str impl = implementation module_name = _IMPLEMENTATION_TO_MODULE_NAME.get(impl, impl.value) diff --git a/tests/dependencies/imports_test.py b/tests/dependencies/imports_test.py index a61e466f2c..ab75560876 100644 --- a/tests/dependencies/imports_test.py +++ b/tests/dependencies/imports_test.py @@ -52,3 +52,20 @@ def test_to_native_namespace_unknown() -> None: AssertionError, match="Cannot return native namespace from UNKNOWN Implementation" ): impl.to_native_namespace() + + +@pytest.mark.parametrize("impl", list(Implementation)) +def test_backend_version(impl: Implementation) -> None: + version: tuple[int, ...] | None + try: + version = impl._backend_version() + except (ModuleNotFoundError, ValueError) as err: + # NOTE: See https://github.com/narwhals-dev/narwhals/issues/2786 + assert impl is not Implementation.UNKNOWN + + with pytest.raises(type(err)): + impl.to_native_namespace() + version = None + + if version is not None: + assert version >= (0, 0, 0)